我想实现 nginx 日志的轮换:
- 无需任何额外软件即可工作(即最好没有“logrotate”)
- 将创建根据日期命名的轮换文件
最好的方法是类似 PostgreSQL 的方法 - 即在它的 log_filename 配置变量中我可以指定 strftime-style %Y-%m-%d,它会在日期(或时间)改变时自动更改日志。
apache 的另一种方法 - 通过管道将日志发送到 rotatelogs 程序。
据我所知,没有这样的方法。我所能做的就是使用带有 dateext 选项的 logrotate,但它有自己的缺点,我宁愿使用像 PostgreSQL 中的 |rotatelogs 或 log_filename 这样的功能。
答案1
虽然人们对这个不起眼的命名管道是敌是友存在分歧,但它可能是解决问题最简单的方法。它确实有一些缺点(因为您需要提前创建管道),但它消除了对 cron 的需求,并允许您使用您选择的日志管道过滤器。
下面是使用 cronolog 的示例access.log
:
- 为我们的命名管道选择一条路径。我打算将日志保存在 中
/var/log/nginx
,因此我也将管道放在那里。名称由您决定;我附加了.fifo
,并且它是access.log
,因此我的将位于/var/log/nginx/access.log.fifo
。 - 如果文件存在则删除它。
为日志文件创建一个命名管道:
mkfifo /var/log/nginx/access.log.fifo
配置
nginx.conf
将日志指向刚刚创建的管道:access_log /var/log/nginx/access.log.fifo;
修改 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
为您处理。只需将命令包装在脚本中,然后将其作为 传递到--exec
中start-stop-daemon
即可init.d/nginx
。
答案2
我编写了一个简单的程序 datelog,用于根据记录日期(而不是程序看到日志行时的当前系统时间)拆分常见日志。这可能与 cronolog 或其他日志拆分程序已经完成的功能完全相同,但编写自己的程序比了解其他人的程序更快。
然后使用记录请求中的年份和月份,将该行写入文件或管道,其中包含根据记录数据计算出的 YYYYMM。是的,这对于通用日志格式来说有些特殊。第一个 [ 假定用于分隔日期。小心 IPv6 地址。:)
对于日志分析来说,重要的是每个日志实际上只包含每个月份的请求,并且每个日志最好是完整的,以便获得正确的分析结果。仅根据日志分割器中的当前时间确定文件名是不够的,因为从 23:59:59 开始的缓慢请求最终会出现在错误月份的日志文件中。
我通过命名 fifo 将其与 nginx 一起使用,在 nginx 启动之前会检查该 fifo 是否存在。请注意,程序中存在错误检测和缓冲输出之间的权衡,其中 datelog 目前出于性能原因更喜欢缓冲输出,因此请确保您的设置确实有效,尤其是在使用 shell 管道时,以免丢失任何日志数据。
请随时向我发送任何反馈,当然还有补丁!
答案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。