社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

Docker 容器日志分析

游戏不存在 • 5 年前 • 457 次点击  
阅读 15

Docker 容器日志分析

查看容器日志

先使用 docker run -it --rm -d -p 80:80 nginx:1.15.8-alpine 命令启动一个nginx容器。如果没有异常,会得到容器ID如 d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00 的长串。再使用 curl -i http://127.0.0.1 访问服务,确认nginx容器正常启动运行。最后使用 docker logs -f d24 查看容器的日志输出,大概如下:

172.17.0.1 - - [24/Mar/2019:03:51:21 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
复制代码

一般来说使用容器ID的前3位即可

以上就是我们查看容器日志的日常方法了,非常简单实用。

容器日志文件存储

容器的日志会以json文件方式存储在本地磁盘,可以使用下面方式查看文件路径 docker inspect d42 | grep Log 可以找到:

"LogPath": "/var/lib/docker/containers/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00-json.log",
复制代码

注意1:mac上没有/var/lib/docker目录 ,因为docker for mac的运作方式不一样,最好使用linux系统练习。

注意2: 如果LogPath内容为空,大概是因为docker engine版本,升级docker版本能到docker-ce 18.09.3

查看 d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00-json.log 文件,可以看到:

{"log":"172.17.0.1 - - [24/Mar/2019:03:51:21 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"curl/7.29.0\" \"-\"\r\n","stream":"stdout","time":"2019-03-24T03:51:21.982476951Z"}
复制代码

这条信息的log字段内容和之前通过 docker logs 命令查看的内容一致。

容器日志会跟随容器生命周期,容器销毁后日志也会销毁。使用 docker stop 24 关停测试的nginx服务。因为容器启动使用时候用了 --rm 参数,关停后会自动清理删除,所以会发现 /var/lib/docker/containers/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00 目录不存在了,相应的日志文件也就删除了。

容器日志文件滚动策略

docker容器日志默认写入json文件,在线上运行时候会有磁盘写满的风险。可以调整策略,让其进行滚动。修改/etc/docker/daemon.json(如果没有就手工创建一个),增加下面内容:

{
  "log-opts": {
    "max-size": "1m",
    "max-file": "3"
  }
}
复制代码

修改完成后重启docker服务:

systemctl daemon-reload
systemctl restart docker.service
复制代码

测试一下新的日志策略,使用下面的命令创建一个容器:

docker run -d --rm alpine:3.6 sh -c "while true; do echo hello world; usleep 10; done"
复制代码

这个alpine容器就是每隔10微秒输出hello world,保持高频度输出,快速生产日志文件。

注:shell中的时间控制
1、sleep : 默认为秒。
sleep 1s 表示延迟一秒  
sleep 1m 表示延迟一分钟  
sleep 1h 表示延迟一小时  
sleep 1d 表示延迟一天    
  
2、usleep : 默认以微秒。  
1s = 1000ms = 1000000us
复制代码

按照前文中查看日志文件的方法

# pwd
/var/lib/docker/containers/aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3
# ls -lah
total 2.6M
drwx------ 4 root root 4.0K Mar 24 16:22 .
drwx------ 3 root root 4.0K Mar 24 16:21 ..
-rw-r----- 1 root root 647K Mar 24 16:22 aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log
-rw-r----- 1 root root 977K Mar 24 16:22 aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log.1
-rw-r----- 1 root root 977K Mar 24 16:21 aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log.2
复制代码

很容易发现,日志文件的策略就是维持3个1m大小文件存在,和我们设置保持一致。

测试完成后,记得使用docker stop aa3 清理测试现场,max-size也可以按照真实需求调整大小。

nginx容器日志

了解docker容器的日志策略后,再看看常用的容器是如何处理的。先看看nginx容器。

首先 docker run -it --rm -d -p 80:80 nginx:1.15.8-alpine 创建一个nginx容器,然后 docker exec -it b6d sh 进入容器,查看/etc/nginx/nginx.conf可以看到下面内容:

error_log  /var/log/nginx/error.log warn;
access_log  /var/log/nginx/access.log  main;
复制代码

也就是nginx会将错误日志和访问日志写入对应的日志文件。继续查看/var/log/nginx目录:

/var/log/nginx # ls -lah
total 0
drwxr-xr-x    2 root     root          39 Mar  4 07:54 .
drwxr-xr-x    3 root     root          18 Mar  4 07:54 ..
lrwxrwxrwx    1 root     root          11 Jan 31 23:32 access.log -> /dev/stdout
lrwxrwxrwx    1 root     root          11 Jan 31 23:32 error.log -> /dev/stderr
复制代码

这就发现奥秘了,access.log文件会通过软链接重定向到标准输出,而错误日志error.log则会重定向标准错误。这样使用docker log命令就可以看到nginx的访问日志了。

为了进一步验证,查看nginx dockerfile文件,其中有:

    # forward request and error logs to docker log collector
	&& ln -sf /dev/stdout /var/log/nginx/access.log \
	&& ln -sf /dev/stderr /var/log/nginx/error.log
复制代码

可见nginx镜像创建时候就定义好了日志文件的输出。

同样使用docker stop 524清理现场,以后就不再介绍清理这一步骤了。

mysql容器日志

启动一个mysql容器

docker run --rm -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
复制代码

不难看到mysql容器日志输出, 截取其中片段如下:

Initializing database
2019-03-24T08:48:19.102726Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2019-03-24T08:48:20.241459Z 0 [Warning] InnoDB: New log files created, LSN=45790
2019-03-24T08:48:20.414933Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2019-03-24T08:48:20.509897Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 935a6ee7-4e11-11e9-b135-0242ac110002.
2019-03-24T08:48:20.519148Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2019-03-24T08:48:20.519843Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2019-03-24T08:48:24.066683Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066730Z 1 [Warning] 'user'


    
 entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066740Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066756Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066761Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066772Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066814Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
2019-03-24T08:48:24.066822Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
Database initialized
Initializing certificates
Generating a RSA private key
复制代码

查看mysql Dockerfile 文件,可以知道mysql镜像启动入口在entrypoint.sh,从脚本中发现:

echo 'Initializing database'
"$@" --initialize-insecure
echo 'Database initialized'
复制代码

这样就是mysql容器启动时候的输出对应起来了。entrypoint.sh比较复杂,主要功能就是启动mysqld,并将日志输出,因为不是本文重点,就不详细介绍了。

总结

  1. docker容器默认输出到本地json文件,并且可以对其进行大小和数量控制。
  2. 应用容器日志可以先生成日志文件,然后将应用日志文件软连接到标准输出,比如nginx;也可以在启动时候直接将日志打印到标准输出,比如mysql。

参考链接

Docker 日志都在哪里?怎么收集?

JSON File logging driver

docker mysql

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30156
 
457 次点击