Ruby 中如何实现日志轮转(Log Rotation)?
Ruby 日志轮转:Logger.new 支持按天/周/月轮转('daily'/'weekly'/'monthly')或按大小轮转(保留个数, 大小)。本文介绍内置方案和 logrotate 配合。
Ruby 的 Logger 内置轮转功能:Logger.new('app.log', 'daily') 按天轮转,Logger.new('app.log', 10, 100.megabytes) 按大小轮转(保留 10 个文件,每个最大 100MB)。
按时间轮转
require 'logger'
# 每天轮转
logger = Logger.new('application.log', 'daily')
# 每周轮转
logger = Logger.new('application.log', 'weekly')
# 每月轮转
logger = Logger.new('application.log', 'monthly')
logger.info("这条日志会被自动轮转")
按大小轮转
require 'logger'
# 保留 10 个日志文件,每个最大 100MB
logger = Logger.new('application.log', 10, 100 * 1024 * 1024)
logger.info("日志到达大小上限时自动轮转")
自定义格式
logger = Logger.new('application.log', 'daily')
logger.formatter = proc do |severity, datetime, progname, msg|
"#{datetime.strftime('%Y-%m-%d %H:%M:%S')} [#{severity}] #{msg}\n"
end
logger.level = Logger::INFO
外部工具:logrotate
也可以不在应用层做轮转,交给系统的 logrotate:
# /etc/logrotate.d/myapp
/var/log/myapp/application.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
copytruncate 让应用不用重新打开文件句柄。
观测云对照
观测云 DataKit 采集日志文件时自动跟踪轮转后的新文件,不需要应用关心轮转逻辑;日志在观测云平台统一存储和检索,本地只保留最近几天的文件即可。
常见问题(FAQ)
Q:按时间轮转后旧文件会自动删除吗?
A:不会。按时间轮转只是创建新文件,需要配合 logrotate 或定期脚本清理旧文件。按大小轮转会自动删除最旧的文件。
Q:多进程写同一个日志文件安全吗?
A:Logger 的轮转在多进程环境下可能出问题(两个进程同时轮转)。建议用 logrotate 的 copytruncate 方案,或让每个进程写独立文件。
Q:Rails 项目怎么做日志轮转?
A:Rails 的 config/environments/production.rb 中配置 config.logger = Logger.new('log/production.log', 'daily'),或让 logrotate 处理。