我在 CentOS 6.5 上运行 Apache 2.2,我想要做的是让 Apache 的当前访问日志文件为:
/var/log/httpd/access_log
并且每天午夜,该文件都会被重命名如下(假设2014-09-22
是刚刚过去的日期):
/var/log/httpd/access_log.2014-09-22
access_log
...此时会创建一个新的日志文件 ( ),Apache 会继续向其中记录日志。我该怎么做?我CustomLog
已经设置了此指令:
CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/access_log.%Y-%m-%d 86400" combined
access_log.2014-09-22
但是,如果今天是 2014-09-22,这会导致当前(活动)日志文件被命名。
我想到了一个 hack 解决方案,我有一个脚本,在午夜后运行,并设置/var/log/httpd/access_log
为指向当天日志文件的符号链接。(它将基于日期,因此即使它是一个低流量服务器并且新日志文件尚不存在,符号链接也将是正确的,并且只要任何请求到达服务器就会起作用)。但似乎必须有一种更优雅的方式来做到这一点。有没有办法告诉轮换日志对当前日志使用一个文件名,对轮换日志使用不同的文件名?如果做不到这一点,还有其他干净的方法来做我想做的事情吗?
编辑:每天重新启动 Apache 不是一个选择。
答案1
看看手册页log rotate
表明dateext
以及 都dateformat
可以用来实现这一目标。
日期文本:归档旧版本的日志文件时,添加每日扩展名(如 YYYYMMDD),而不是简单地添加数字。可以使用 dateformat 选项配置扩展名。
日期格式(format_string):使用与 strftime(3) 函数类似的符号指定日期扩展名。仅允许使用 %Y %m %d 和 %s 说明符。默认值为 -%Y%m%d。请注意,将日志名称与扩展名分隔开的字符也是日期格式字符串的一部分。系统时钟必须设置为 2001 年 9 月 9 日之后,%s 才能正常工作。请注意,此格式生成的日期戳必须是可按词汇排序的(即,首先是年份,然后是月份,然后是日期。例如,2001/12/01 可以,但 01/12/2001 不行,因为 01/11/2002 排序较低,而它较晚)。这是因为当使用 rotate 选项时,log rotate 会对所有轮换的文件名进行排序,以找出哪些日志文件较旧且应被删除。
因此,使用logrotate
我在 Ubuntu 上设置 Apache 时使用的相当简单的脚本,您可以执行以下操作:
/var/log/apache2/*.log {
weekly
missingok
rotate 26
compress
dateext
dateformat %Y-%m-%d
delaycompress
notifempty
create 640 root www-data
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi; \
endscript
}
答案2
使用纪年法。
CustomLog "|/usr/sbin/cronolog \
-S /var/log/httpd/access_log
/var/log/httpd/access_log.%Y-%m-%d" combined
这类似于您的“黑客解决方案”,因为每个日志都将命名为 access_log.YYYY-MM-DD ,包括活动日志。但 cronolog 将为您维护符号链接 (-S),以便 /var/log/httpd/access_log 始终指向当前日志。作为奖励,当日期滚动时,这将自动发生 - 无需 logrotate cron 作业。