做运维或者开发的兄弟都懂,日志是排查问题的第一道线索。但你有没有遇到过这种情况:明明昨天下午三点报的错,翻日志却在今天的文件里?或者定时任务触发的日志,莫名其妙地出现在前后两天的文件中?十有八九,是日志轮转碰上了时区问题。
日志轮转为啥会跟时区扯上关系
很多服务默认按天轮转日志,比如 app.log 到了凌晨就变成 app.log.2024-04-05。系统判断“新的一天”靠的是本地时间,而这个时间是基于时区的。如果你服务器跑在 UTC 时区,而业务用户都在中国,那每天的“日切”其实是北京时间早上八点。八点前的错误日志全被归到前一天的文件里,查起来能不抓狂吗?
常见出问题的场景
举个例子:你在阿里云买了一台 ECS,默认时区是 UTC。部署了个 Node.js 服务,用 winston 做日志,配置按天切割。结果用户早上七点反馈接口异常,你去查 error.log.2024-04-05,啥都没有。一瞅系统时间,原来是 UTC 的 4 月 4 日 23:00,日志还写在当天的文件里。等你反应过来,已经浪费半小时。
怎么治这个毛病
最直接的办法:统一时区。服务器时区设成 Asia/Shanghai,应用层也别用 UTC 时间做日志命名。Linux 下可以用命令:
timedatectl set-timezone Asia/Shanghai
如果是 Docker 环境,别忘了在容器里也设置:
environment:
- TZ=Asia/Shanghai
另外,像 Logrotate 这种工具,虽然本身不支持指定时区,但你可以通过调整轮转时间避开坑。比如把轮转时间从 00:00 改成 08:00,并配合 cron 在北京时间凌晨八点执行:
0 8 * * * /usr/sbin/logrotate /etc/logrotate.d/myapp
应用层也要注意
Java 项目用 Logback?记得检查 <fileNamePattern> 里的日期格式有没有带时区。Python 的 logging 模块如果结合 TimedRotatingFileHandler,可以传入 utc=False 参数,让它用本地时间判断切割时机。
Go 语言里有些日志库默认用 UTC 时间生成文件名,得手动改配置。别偷懒,上线前多跑一遍跨日测试,模拟时区切换,看看日志落盘对不对。
监控和告警也得跟着调
你用 Prometheus + Grafana 看日志指标?如果日志文件的时间戳和系统时间对不上,告警阈值可能失灵。比如统计“过去一小时错误数”,结果因为时区错乱,程序去查了错误的文件,漏报了问题。这种隐患比宕机还可怕。
解决这类问题没有银弹,关键是保持整个链路的时间一致性:系统、容器、应用、日志工具、监控平台,全都对齐到同一个时区。别觉得“UTC 更标准”就一路到底,业务在哪,时间就得跟到哪。