旋转Nginx日志的正确方法


12

我想实现nginx日志的轮换:

  1. 无需任何额外的软件即可工作(即,如果没有“ logrotate”,则最好)
  2. 将根据日期创建旋转文件

最好的方法就像PostgreSQL一样-即在它的log_filename配置变量中,我可以指定strftime风格的%Y-%m-%d,它将自动更改登录日期(或时间)的更改。

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

据我所能搜索-没有这种方法。我所能做的就是将logrotate和dateext选项一起使用,但是它有其自身的缺点,我宁愿使用类似PostgreSQL中的| rotatelogs或log_filename的功能。


这篇博客文章描述了您的问题的可能解决方案。但是我有一个问题:您为什么不想使用logrotate?它做得很好,几乎没有依赖关系,并且被证明可以工作(如果可以的话,可以进行战斗加固)。如果您仅可以使用logrotate(这对于在该计算机上旋转某些其他日志也可能有用),为什么还要跳过箍并使用本地的解决方案,该解决方案可能会比较差且容易出错?
joschi

logrotate(使用dateext)几乎可以工作,但是我不喜欢它,因为它必须通过cron运行,这有一些缺点。

由于nginx不支持将其日志传送到其他程序,也不单独支持日志轮换,并且您不喜欢基于cron的方法,因此可能无法完全获得所需的内容。有时,“几乎可行”是最好的。;)当然,除非您想自己修补nginx。
joschi

Answers:


7

尽管对于不起眼的命名管道是敌是友,世界各有不同,但这可能是解决问题的最简单方法。它确实有一些缺点(因为您需要提前创建管道),但是它消除了对cron的需求,并允许您使用所选的日志记录管道过滤器。

这是使用cronolog on的示例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


我喜欢cronolog;很高兴看到更多人使用/推荐它。
natacado

1

我编写了一个简单的程序datelog,用于根据记录的日期分割普通日志,而不是程序看到日志行时的当前系统时间。这可能不是cronolog或其他日志拆分器已经做的,也可能不是,但是写我自己的日志比找出其他人做的更快。

然后,使用记录的请求中的年和月,将行写入包含从记录的数据计算出的YYYYMM的文件或管道中。是的,这是特定于通用日志格式的。假定第一个[分隔日期。提防IPv6地址。:)

对于日志分析,重要的是每个日志实际上只包含每个月的请求,并且理想情况下,每个日志应该完整以获取正确的分析结果。仅根据日志拆分器中的当前时间来确定文件名是不够的,因为从23:59:59开始的缓慢请求将最终在错误月份的日志文件中结束。

我通过一个名为fifo的方式将它与nginx一起使用,在启动nginx之前已检查其是否存在。请注意,在程序中,要在错误检测和缓冲输出之间进行权衡,出于性能方面的考虑,datelog当前首选缓冲输出,因此请确保您的设置确实有效,尤其是在使用shell管道时,以免丢失任何日志数据。

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

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


1

您可以使用简单的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日志文件


0

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

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

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


这与我使用logrotate所做的相同。我希望它更好。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.