日志轮转总差8小时?一招搞定时区错乱问题

家里搭了个NAS,又顺手在树莓派上跑了个小博客,结果发现每天凌晨3点的日志文件,名字却标着03:00,而系统实际时间是11:00——查了下,原来是日志轮转(logrotate)用的是UTC时间,本地却设的是CST(东八区),差了整整8小时。

为啥logrotate不认你电脑的时区?

logrotate本身不读取系统时区设置(比如/etc/timezone或TZ环境变量),它默认按UTC时间判断轮转时机。哪怕你date命令显示的是“2024年6月12日 11:23:45 CST”,logrotate仍可能按UTC的03:23来切日志,于是凌晨三点生成的文件,内容却是前一天晚上的访问记录,排查问题时翻半天才反应过来:哦,这根本不是“今天”的日志。

改配置,让它听你的时区

关键在logrotate配置里加一行:dateformat配合dateext使用。比如你想让日志按“20240612”这种格式命名,并且严格按本地时间(比如上海时间)轮转:

/var/log/myapp/*.log {
daily
missingok
rotate 30
compress
dateext
dateformat -%Y%m%d-%H%M%S
timezone Asia/Shanghai
}

注意:timezone这一行是logrotate 3.11.0+才支持的(Ubuntu 22.04+/Debian 12+ 默认带)。如果版本太老,升级logrotate最省事:sudo apt update && sudo apt install logrotate

没升级条件?临时绕过也行

老系统不想动,可以换思路:不用daily,改用hourly + 脚本判断。比如在crontab里手动触发轮转:

# 每天凌晨2:10执行(避开系统默认UTC轮转时间)
10 2 * * * /usr/bin/logrotate /etc/logrotate.d/myapp --force

再配合dateformat -%Y%m%d,确保生成的文件名是你看得懂的日期,比如app.log-20240612,而不是app.log-20240611(UTC昨天)。

验证有没有生效?

别光看配置,动手试一试:

sudo logrotate -d /etc/logrotate.d/myapp

-d参数会打印调试信息,重点看这行:
rotating pattern: /var/log/myapp/*.log after 1 days (7 rotations)
下面如果出现switching to timezone 'Asia/Shanghai',就说明时区已接管。

顺手把/var/log/myapp/下的旧日志删掉几个,跑一次sudo logrotate -f /etc/logrotate.d/myapp,看看新文件名是不是你本地当前日期——对上了,问题就算落地了。