我们可以使用 docker logs 命令查看 Docker 容器内部应用程序运行时所产生的日志。
docker logs -f -t [容器id]
使用 docker logs 命令可以免除首先进入 Docker 容器,再打开应用程序的日志文件的过程。docker logs 会监控容器中操作系统的
标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另一个“设备”中,该 Docker 的驱动被称为“日志驱动”(Logging Driver)
Docker 提供多种日志驱动程序,可以帮助你从正在运行的容器和服务中获取信息。
每个 Docker 守护进程都有一个默认的日志驱动程序,如果你没有将其配置为使用其他日志驱动程序,则每一个容器都会使用这个默认配置(默认的日志驱动程序 json-file)。
支持的日志驱动程序如下:
驱动程序 | 描述 |
---|---|
none | 容器没有日志可用,docker logs 什么都不返回 |
json-file | 日志格式化为 JSON。这是 Docker 默认的日志驱动程序。 |
syslog | 将日志消息写入 syslog 工具。syslog 守护程序必须在主机上运行。 |
journald | 将日志消息写入 journald。journald 守护程序必须在主机上运行。 |
gelf | 将日志消息写入 Graylog Extended Log Format (GELF) 终端,例如 Graylog 或 Logstash。 |
fluentd | 将日志消息写入 fluentd(forward input)。fluentd 守护程序必须在主机上运行。 |
awslogs | 将日志消息写入 Amazon CloudWatch Logs。 |
splunk | 将日志消息写入splunk使用HTTP事件收集器。 |
etwlogs | 将日志消息写为 Windows 的 Event Tracing 事件。仅在Windows平台上可用。 |
gcplogs | 将日志消息写入 Google Cloud Platform (GCP) Logging。 |
logentries | 将日志消息写入 Rapid7 Logentries。 |
要配置 Docker 守护进程默认使用指定的日志驱动程序,我们需要将 daemon.json 文件(Linux 中一般位于 /etc/docker/,Windows 中一般位于 C:\ProgramData\docker\config\)中的 log-driver 值设为日志驱动程序的名字即可。默认的日志驱动程序 json-file。下面例子将其设置为 syslog:
{
"log-driver": "syslog"
}
如果日志驱动程序有可配置的选项,可以在 daemon.json 文件的关键字 log-opts 中以 JSON 格式设置。下面示例为 json-file 日志驱动程序设置了几个可配置选项:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"labels": "production_status",
"env": "os,customer"
}
}
参数说明
参数 | 描述 |
---|---|
max-size | 容器日志文件上限大小 |
max-file | 容器日志文件上限个数 |
labels | 容器日志标签 |
env | 容器日志环境变量 |
如果你没有指定日志驱动程序,默认就是 json-file。如果你想查看当前Dokcer守护进程的默认日志驱动程序,可以运行 docker info 命令并在输出中查找 Logging Driver。下面命令可以在 Linux、macOS 或 Windows 上使用:
$ docker info | grep 'Logging Driver'
Logging Driver: json-file
在启动容器时,可以通过 --log-driver 标签将其配置为使用与 Docker 守护进程不同的日志驱动程序。如果日志驱动程序有可配置的选项,可以通过一个或多个 --log-opt = 来设置。即使容器使用的是默认的日志驱动程序,也可以使用不同的配置选项。
下面的例子启动了一个使用 none 日志驱动程序的 nginx 容器。
docker run -d --name nginx01 -p 3345:80 --log-driver none nginx
在使用 json-file 和 journald 之外的日志驱动程序时 docker logs 命令不可用。
下面的例子查看了一个使用 none 日志驱动程序的 nginx 容器的日志,容器id是f3499b2ded4e
$ docker logs f3499b2ded4e
Error response from daemon: configured logging driver does not support reading
在使用 json-file 之外的日志驱动程序时,不会在/var/lib/docker/contailers/[容器id]/目录下生成:容器id-json.log 这个文件
要找出一个运行中的容器当前使用的日志驱动程序,可以使用 docker inspect 命令查看。
下面的例子查看了一个使用 none 日志驱动程序的 nginx 容器,容器id是f3499b2ded4e
docker inspect f3499b2ded4e
可以在容器的详细信息中找到如下信息,Type就是容器当前使用的日志驱动程序
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "none",
"Config": {}
},
我们可以通过docker inspect的查找命令,精确的找到容器当前使用的日志驱动程序。
下面的例子查看了一个使用 none 日志驱动程序的 nginx 容器,容器id是f3499b2ded4e
$ docker inspect -f '{{.HostConfig.LogConfig.Type}}' f3499b2ded4e
none
容器数据卷是容器之间的一个数据共享的技术。即可以把Docker容器中产生的数据,同步到本地。这种技术也可以称为目录的挂载。
在启动容器时,可以通过 -v 标签将其配置为挂载容器内的某个地址到本地的某个地址上,我们可以把容器中应用产生的日志地址挂载到本地。
下面的例子启动了一个tomcat容器,把tomcat容器内的/usr/local/tomcat/logs挂载到本地的/home/tomcat/log下。
docker run -d -p 3355:8080 -v /home/tomcat/log:/usr/local/tomcat/logs --name tomcat01 tomcat
启动后,我们可以在本地的的/home/tomcat/log目录下看到tomcat的5个日志文件
$ ls /home/tomcat/log/
catalina.2021-05-26.log host-manager.2021-05-26.log localhost.2021-05-26.log localhost_access_log.2021-05-26.txt manager.2021-05-26.log
cat /home/tomcat/log/catalina.2021-05-26.log
Docker 提供多种日志驱动程序,其默认的日志驱动程序是 json-file。
在使用 json-file 的日志驱动程序时,会在/var/lib/docker/contailers/[容器id]/目录下生成:容器id-json.log 这个文件。
下面的例子查看了一个tomcat容器的json-file日志文件,容器id为819c7f41b067
cd /var/lib/docker/containers/819c7f41b067a44cc268bdb752a22632a5c0af905e2b5bef288daf229f27cfe7/
cat 819c7f41b067a44cc268bdb752a22632a5c0af905e2b5bef288daf229f27cfe7-json.log
下面的例子对比了两种日志驱动文件
方案一中挂载出来的日志catalina.2021-05-26.log :
26-May-2021 06:40:40.459 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/9.0.46
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: May 8 2021 17:35:52 UTC
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.46.0
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 3.10.0-1062.el7.x86_64
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/openjdk-11
26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 11.0.11+9
26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
26-May-2021 06:40:40.470 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
26-May-2021 06:40:40.470 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
方案二中819c7f41b067a44cc268bdb752a22632a5c0af905e2b5bef288daf229f27cfe7-json.log :
{"log":"NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED\n","stream":"stderr","time":"2021-05-26T06:40:40.202770445Z"}
{"log":"26-May-2021 06:40:40.459 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/9.0.46\n","stream":"stderr","time":"2021-05-26T06:40:40.461584112Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: May 8 2021 17:35:52 UTC\n","stream":"stderr","time":"2021-05-26T06:40:40.46164358Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.46.0\n","stream":"stderr","time":"2021-05-26T06:40:40.461738479Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux\n","stream":"stderr","time":"2021-05-26T06:40:40.461829336Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 3.10.0-1062.el7.x86_64\n","stream":"stderr","time":"2021-05-26T06:40:40.46189656Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64\n","stream":"stderr","time":"2021-05-26T06:40:40.46197324Z"}
{"log":"26-May-2021 06:40:40.461 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/openjdk-11\n","stream":"stderr","time":"2021-05-26T06:40:40.462042184Z"}
{"log":"26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 11.0.11+9\n","stream":"stderr","time":"2021-05-26T06:40:40.462138695Z"}
{"log":"26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation\n","stream":"stderr","time":"2021-05-26T06:40:40.462233917Z"}
{"log":"26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat\n","stream":"stderr","time":"2021-05-26T06:40:40.462266616Z"}
{"log":"26-May-2021 06:40:40.462 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat\n","stream":"stderr","time":"2021-05-26T06:40:40.462343751Z"}
{"log":"26-May-2021 06:40:40.470 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED\n","stream":"stderr","time":"2021-05-26T06:40:40.470945176Z"}
{"log":"26-May-2021 06:40:40.470 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED\n","stream":"stderr","time":"2021-05-26T06:40:40.470987618Z"}
可以看到通过方案二采集到的容器日志,是被json-file日志驱动做了一层json包装的日志文件。
所以如果我们使用方案二来采集容器日志,只能使用json_log的解析规则解析日志文件。