美文网首页Java高级进阶
滚动 docker 中的 nginx 日志

滚动 docker 中的 nginx 日志

作者: java菜 | 来源:发表于2018-11-08 15:12 被阅读3次

Nginx 自己没有处理日志的滚动问题,它把这个球踢给了使用者。一般情况下,你可以使用 logrotate 工具来完成这个任务,或者如果你愿意,你可以写各式各样的脚本完成同样的任务。本文笔者介绍如何滚动运行在 docker 中的 nginx 日志文件(下图来自互联网)。

思路

Nginx 官方其实给出了如何滚动日志的说明:Rotating Log-filesIn order to rotate log files, they need to be renamed first. After that USR1 signal should be sent to the master process. The master process will then re-open all currently open log files and assign them an unprivileged user under which the worker processes are running, as an owner. After successful re-opening, the master process closes all open files and sends the message to worker process to ask them to re-open files. Worker processes also open new files and close old files right away. As a result, old files are almost immediately available for post processing, such as compression.

这段说明的大意是:

先把旧的日志文件重命名

然后给 nginx master 进程发送 USR1 信号

nginx master 进程收到信号后会做一些处理,然后要求工作者进程重新打开日志文件

工作者进程打开新的日志文件并关闭旧的日志文件

其实真正需要我们做的工作只有前面两点!

创建测试环境

假设你的系统中已经安装好了 docker,这里我们直接运行一个 nginx 容器:

$ docker run -d \    -p 80:80 \    -v $(pwd)/logs/nginx:/var/log/nginx \    --restart=always \    --name=mynginx \    nginx:1.11.3

注意,我们把 nginx 的日志绑定挂载到了当前目录下的 logs 目录下。

把下面的内容保存到 test.sh 文件中:

#!/bin/bash  for ((i=1;i<=100000;i++)) do    curl http://localhost > /dev/null sleep 1 done

然后运行这个脚本,就可以模拟产生连续的日志记录。

创建滚动日志的脚本

创建 rotatelog.sh 文件,其内容如下:

#!/bin/bash  getdatestring() {    TZ='Asia/Chongqing' date "+%Y%m%d%H%M" } datestring=$(getdatestring)  mv /var/log/nginx/access.log /var/log/nginx/access.${datestring}.log mv /var/log/nginx/error.log /var/log/nginx/error.${datestring}.log kill -USR1 `cat /var/run/nginx.pid`

getdatestring 函数取当前的时间并格式化为字符串,比如 "201807241310",笔者比较喜欢用日期和时间来命名文件。注意这里通过 TZ='Asia/Chongqing' 指定了时区,因为默认情况下格式化的是 UTC 时间,用起来怪怪的(要实时脑补 +8 小时)。下面的两条 mv 命令用来重命名日志文件。最后通过 kill 命令向 nginx master 进程发送 USR1 信号。

通过下面的命令为 rotatelog.sh 文件添加可执行权限并复制到 $(pwd)/logs/nginx 目录下:

$ chmod +x rotatelog.sh $ sudo cp rotatelog.sh $(pwd)/logs/nginx

定时执行滚动操作

我们的 nginx 运行在容器中,所以需要在容器中给 nginx master 进程发送 USR1 信号。因此我们需要通过 docker exec 命令在 mynginx 容器中执行 rotatelog.sh 脚本:

$ docker exec mynginx bash /var/log/nginx/rotatelog.sh

执行一次上面的命令,会如期产生一批新的日志文件:

下面我们把这个命令配置在定时任务中,让它每天早上 1 点钟执行一次。执行 crontab -e 命令,并在文件的末尾添加下面的行:

* 1 * * * docker exec mynginx bash /var/log/nginx/rotatelog.sh

保存并退出就可以了。下图是笔者测试过程中每 5 分钟滚动一次的效果:

为什么不在宿主机中直接 mv 日志文件?

理论上这么做是可以的,因为通过绑定挂载的数据卷中的内容从宿主机上看和从容器中看都是一样的。但是真正这么做的时候你很可能碰到权限问题。在宿主机中,你一般使用的是普通用户,而在容器中产生的日志文件的所有者是会是特殊的用户,并且一般不会给其它用户写和执行的权限:

当然,如果你在宿主机中使用的是 root 用户就不会有问题。

能从宿主机中发送的信号吗?

其实这个问题的全称应该是:能从宿主机中给 docker 容器中的 nginx master 进程发送信号吗?

答案是,可以的。在文章中我们介绍了 docker 向容器中进程发送信号的 kill 命令。我们可以通过命令:

$ docker container kill mynginx -s USR1

向容器中的 1 号进程(nginx master)发送 USR1 信号(这种方式只能向 1 号进程发送信号):

结合上面的两个问题,我们可以写出另外的一种方式来滚动 docker 中的 nginx 日志。这种方式不需要通过 docker exec 命令在容器中执行命令,而完全在宿主机中完成所有的操作:

先重命名容器数据卷中的日志文件

给容器中的 1 号进程发送 USR1 信号

总结

相比之下我还是更喜欢第一种方式,它逻辑上清晰,操作上几乎与宿主机完全隔离,也不容易出错。但是通过第二种方式的尝试,我们不但可以找到新的实现方式,还会加深对容器操作的理解。学而不思则罔啊!

欢迎工作一到五年的Java工程师朋友们加入Java架构开发: 854393687

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

相关文章

  • 滚动 docker 中的 nginx 日志

    Nginx 自己没有处理日志的滚动问题,它把这个球踢给了使用者。一般情况下,你可以使用 logrotate 工具来...

  • 滚动 docker 中的 nginx 日志

    Nginx 自己没有处理日志的滚动问题,它把这个球踢给了使用者。一般情况下,你可以使用 logrotate 工具来...

  • Logstash采集Nginx日志写入ES

    Logstash采集Nginx日志方式 RPM安装Logstash采集Nginx日志 Docker安装Logsta...

  • Docker 日志整合 syslog

    一、了解 Docker 日志 我们以 nginx 为例来了解 docker log。 启动 nginx 容器: 访...

  • Nginx 使用 logrotate 进行日志滚动

    Nginx 日志滚动(官方) 向 Nginx 主进程发送 USR1 信号。 USR1 信号量被 Nginx 自定义...

  • Docker 安装并配置 nginx

    1.安装 docker pull nginx 2.docker 中启动nginx docker run --nam...

  • nginx的日志配置

    1. nginx中日志的种类 nginx中可以记录的日志主要有access日志、error日志和rewrite日志...

  • Python中的logging使用

    Python中自带了logging库,可以提供打印日志、记录日志文件、根据时间日志滚动、根据文件大小日志滚动、过期...

  • docker-cmd

    CentOS 7 中 Docker 的安装 CentOS 7 使用Docker搭建Nginx Docker容器内部...

  • nginx日志分析

    1,日志定义 在nginx.conf中定义的日志格式如下: 日志文件如下: 2,日志分割 nginx没有命令直接将...

网友评论

    本文标题:滚动 docker 中的 nginx 日志

    本文链接:https://www.haomeiwen.com/subject/ifswxqtx.html