轮换 Nginx 日志的正确方法

轮换 Nginx 日志的正确方法

我想实现 nginx 日志的轮换:

  1. 无需任何额外软件即可工作(即最好没有“logrotate”)
  2. 将创建根据日期命名的轮换文件

最好的方法是类似 PostgreSQL 的方法 - 即在它的 log_filename 配置变量中我可以指定 strftime-style %Y-%m-%d,它会在日期(或时间)改变时自动更改日志。

apache 的另一种方法 - 通过管道将日志发送到 rotatelogs 程序。

据我所知,没有这样的方法。我所能做的就是使用带有 dateext 选项的 logrotate,但它有自己的缺点,我宁愿使用像 PostgreSQL 中的 |rotatelogs 或 log_filename 这样的功能。

答案1

虽然人们对这个不起眼的命名管道是敌是友存在分歧,但它可能是解决问题最简单的方法。它确实有一些缺点(因为您需要提前创建管道),但它消除了对 cron 的需求,并允许您使用您选择的日志管道过滤器。

下面是使用 cronolog 的示例access.log

  1. 为我们的命名管道选择一条路径。我打算将日志保存在 中/var/log/nginx,因此我也将管道放在那里。名称由您决定;我附加了.fifo,并且它是access.log,因此我的将位于/var/log/nginx/access.log.fifo
  2. 如果文件存在则删除它。
  3. 为日志文件创建一个命名管道:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. 配置nginx.conf将日志指向刚刚创建的管道:

    access_log /var/log/nginx/access.log.fifo;
    
  5. 修改 init.d 脚本以启动监听管道的日志旋转器我们启动服务器:

    LOGS="/var/log/nginx"
    pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
    ( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
    

    rotatelogs如果您愿意,可以使用类似的命令行cronolog- 请参阅其文档以了解语法。

    如果您的发行版有start-stop-daemon,则应使用它,因为理论上它具有有关您的平台的任何特殊知识,并pkill为您处理。只需将命令包装在脚本中,然后将其作为 传递到--execstart-stop-daemon即可init.d/nginx

答案2

我编写了一个简单的程序 datelog,用于根据记录日期(而不是程序看到日志行时的当前系统时间)拆分常见日志。这可能与 cronolog 或其他日志拆分程序已经完成的功能完全相同,但编写自己的程序比了解其他人的程序更快。

然后使用记录请求中的年份和月份,将该行写入文件或管道,其中包含根据记录数据计算出的 YYYYMM。是的,这对于通用日志格式来说有些特殊。第一个 [ 假定用于分隔日期。小心 IPv6 地址。:)

对于日志分析来说,重要的是每个日志实际上只包含每个月份的请求,并且每个日志最好是完整的,以便获得正确的分析结果。仅根据日志分割器中的当前时间确定文件名是不够的,因为从 23:59:59 开始的缓慢请求最终会出现在错误月份的日志文件中。

我通过命名 fifo 将其与 nginx 一起使用,在 nginx 启动之前会检查该 fifo 是否存在。请注意,程序中存在错误检测和缓冲输出之间的权衡,其中 datelog 目前出于性能原因更喜欢缓冲输出,因此请确保您的设置确实有效,尤其是在使用 shell 管道时,以免丢失任何日志数据。

源代码:http://stuge.se/datelog.c

请随时向我发送任何反馈,当然还有补丁!

答案3

您可以使用简单的 bash 脚本和 cron 实现此目的:

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

关于设置 crontab 等的更多详细信息请参见此处:通过 Cron 轮换 Nginx 日志文件

答案4

恐怕我不太明白你的问题:由于 nginx 不支持任何内置的 logrotation,因此你必须使用类似

mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)

/etc/cron.daily 中的某个位置(当然,您需要用完整路径名限定上述文件名)或安装 apache2 实用程序才能访问 rotatelogs。

相关内容