使用OpsWorks t2.medium实例运行Ruby Clockwork遇日志轮转锁失败求助
解决Ruby Clockwork在OpsWorks中日志轮转锁失败的问题
我来帮你搞定这个头疼的问题!从你描述的错误log rotation inter-process lock failed. No such file or directory @ rb_sysopen - log/sql.log来看,核心问题出在日志轮转时的文件权限、路径或者进程竞争上,结合Clockwork每30秒触发任务的场景,下面是一步步的排查和解决方法:
1. 先搞定基础:日志目录的存在性与权限
首先最常见的原因是log目录不存在或者Clockwork进程没有读写权限:
- 登录到你的t2.medium实例,运行
ls -ld /path/to/your/app/log/(替换成你实际的应用路径),检查目录是否存在,以及运行Clockwork的用户(比如OpsWorks默认的deploy用户)是否有读写权限。 - 如果目录不存在,在Clockwork的启动代码最开头添加自动创建目录的逻辑:
log_file_path = 'log/sql.log' log_dir = File.dirname(log_file_path) # 递归创建目录,确保父目录也存在 Dir.mkdir(log_dir, 0755) unless Dir.exist?(log_dir)
这样能避免启动或轮转时找不到目录的问题。
2. 替换Ruby Logger内置轮转:改用系统logrotate
Ruby自带的Logger轮转机制是进程内实现的,对于长时间运行的Clockwork服务(尤其是多进程场景),很容易出现锁冲突或文件找不到的问题。改用Linux系统的logrotate工具会更稳定:
- 在实例上创建logrotate配置文件:
sudo vi /etc/logrotate.d/clockwork_sql,填入以下内容(替换成你的实际日志路径):
/var/www/your-app/log/sql.log { rotate 7 # 保留7天的日志 daily # 每天轮转一次 missingok # 如果日志文件不存在也不报错 notifempty # 空文件不轮转 compress # 压缩旧日志 delaycompress # 延迟压缩,保留最新的旧日志不压缩 copytruncate # 复制日志内容后截断原文件,避免进程找不到文件 create 644 deploy deploy # 轮转后创建新文件,设置正确的权限和用户 }
- 测试配置是否生效:运行
sudo logrotate -v /etc/logrotate.d/clockwork_sql,检查输出有没有错误。 - 这个方案的核心是
copytruncate,它不会移动或删除原日志文件,只是截断,Clockwork进程不需要重新打开文件,完美解决"找不到文件"的问题。
3. 确保只有一个Clockwork进程在运行
OpsWorks的部署流程有时候会导致旧的Clockwork进程没有被彻底杀死,多个进程同时写同一个日志文件,必然会引发锁冲突:
- 部署时在OpsWorks的deploy hooks里添加清理旧进程的脚本(比如在
after_restart阶段):
# 杀死所有Clockwork进程,不存在也不报错 pkill -f clockwork || true # 然后启动新的Clockwork进程 bundle exec clockwork lib/clock.rb
- 平时也可以用
ps aux | grep clockwork检查进程数量,确保只有一个实例在运行。
4. 优化Logger的错误处理(可选)
如果坚持用Ruby Logger的内置轮转,可以添加错误捕获和日志重开的逻辑,避免进程直接挂掉:
def setup_logger logger = nil begin # 这里用你的轮转配置,比如daily/weekly或者按大小轮转 logger = Logger.new('log/sql.log', 'daily') logger.level = Logger::INFO rescue Errno::ENOENT => e # 目录不存在时创建后重试 log_dir = File.dirname('log/sql.log') Dir.mkdir(log_dir, 0755) unless Dir.exist?(log_dir) retry end # 添加HUP信号处理,收到信号时重新打开日志文件(配合logrotate使用) Signal.trap('HUP') do logger.reopen('log/sql.log') end logger end # 初始化logger logger = setup_logger
按照上面的步骤逐一排查,应该就能解决日志轮转锁失败和Clockwork挂掉的问题了!
内容的提问来源于stack exchange,提问作者shakeel
相关产品推荐
相关产品推荐

