运维 Rails log 自动分割该怎么配置才正确

huacnlee · 2012年06月07日 · 最后由 glz1992 回复于 2016年01月07日 · 13975 次阅读
本帖已被管理员设置为精华贴

Rails 产品环境的 production.log 越来越大,自己尝试着给他加分割的动作,结果跑了一段时间以后发现没有成功

app/config/environments/production.rb

config.logger = Logger.new("#{Rails.root}/log/#{Rails.env}.log",7)
# 也尝试过
config.logger = Logger.new("#{Rails.root}/log/#{Rails.env}.log",'weekly')

结果日志文件变成这样了:

-rw-rw-r-- 1 jason jason  145 Jun  5 09:40 log/production.log.20120602.1
-rw-rw-r-- 1 jason jason  151 Jun  5 10:23 log/production.log.20120602.10
-rw-rw-r-- 1 jason jason  150 Jun  5 10:24 log/production.log.20120602.11
-rw-rw-r-- 1 jason jason  150 Jun  5 11:12 log/production.log.20120602.12
-rw-rw-r-- 1 jason jason 360K Jun  5 16:58 log/production.log.20120602.13
-rw-rw-r-- 1 jason jason  151 Jun  5 11:34 log/production.log.20120602.14
-rw-rw-r-- 1 jason jason  151 Jun  5 11:34 log/production.log.20120602.15
-rw-rw-r-- 1 jason jason  144 Jun  5 11:37 log/production.log.20120602.16
-rw-rw-r-- 1 jason jason  144 Jun  5 11:38 log/production.log.20120602.17
-rw-rw-r-- 1 jason jason  151 Jun  5 11:39 log/production.log.20120602.18
-rw-rw-r-- 1 jason jason  151 Jun  5 11:39 log/production.log.20120602.19
...
还有很多,都是 20120602 的

而不是相像的那样,7 天分割一个

差了好多地方,看起来他们也是这么配置的

用 supervisord 吧

我之前的做法是 rails 不设置分割日志

而在系统中用 logrotate 或者其他的日志管理工具进行分割或其它维护操作

一般来说是可以很稳定运行的

logrotate 配置麻烦,尤其是多个服务器的时候,所以一直想找 Rails 内置方式

#4 楼 @huacnlee 要内置很难搞的吧,进程 fork 出来的时候,没法知道有没有其他在写日志的进程存在。

#5 楼 @bhuztez 目前我的写成那样应该就是这个原因吧

个人认为日志管理属于系统范畴。之前我也尝试过 Rails 内置,但是发现在日志文件切换的时候会产生一些莫名其妙的问题,会产生一些 bug(当时是 rails 2.3.5) 。 后来放弃了,换成 logrotate 就很稳定了。 另外如果是多台服务器配置是否可以考虑使用 Puppet 等工具进行配置管理呢?

logrotate 是以 cron job 的形式运行的,每次运行的时候可以制定一个配置文件,所以你可以这样:

/usr/sbin/logrotate /path/to/rails/project/config/logrotate.conf

然后用 when 这个 gem 去设置 cron job 就可以啦

set log_path = "log";
set to_day = `date -d "yesterday" +"%Y%m%d"`;
cd ${log_path}
cp ${log_path}/production.log ${log_path}/production_${to_day}.log
echo "" > ${log_path}/production.log
chown www:www ${log_path}/production.log
bzip2 ${log_path}/production_${to_day}.log

我的是跑任务,这样如果想发到别的服务器上也可以

#9 楼 @hooopo 可以给个源链接吗

#9 楼 @hooopo 确实国外的很多公司都是使用标准输出进行集中化的日志管理,我看过美国公司的代码都是这样使用的。

#9 楼 @hooopo 前段时间我也尝试这用了一下 Fluentd,确实非常好

#12 楼 @zmbacker 这样做还有一个好处是一个应用的 web server,app server,worker 等的日志是按时间顺序在一起的,更能清晰反应应用运行情况。

logrotate 的配置挺简单的呀。

/home/xxoo.com/www/log/*.log {
    daily
    missingok
    rotate 3
    compress
    delaycompress
    notifempty
    create 664 nobody nobody
    sharedscripts
    postrotate
        /etc/init.d/nginx reload > /dev/null
    endscript
} 

内置的不靠谱的,尤其是有多个 ruby 实例的时候,用外部的 cron 之类的会好很多 实在嫌麻烦,你用 whenever 写个脚本定期执行 mv 也行啊

果然是内置的不靠谱啊,我前一段时间还以为是自己的做法有问题

#19 楼 @huacnlee 为什么 lastaction 要 kill unicorn 的进程?

#22 楼 @quakewang USR1 是告诉 unicorn 重新加载日志文件,因为 logrogate 会把 production.log 移走

#22 楼 @quakewang 最新版的 thin 也支持这种给进程发送信号来重新加载日志的特性

#23 楼 @huacnlee #24 楼 @hooopo

原来是这个原因,一直用 copytruncate 配置 logrotate, 没想到日志文件被一直打开的问题.:)

@huacnlee 前面都懂,那个脚本里面我没有找到 pid=/data/www/ruby-china/current/tmp/pids/nginx.pid,用 nginx 该怎么写 - -

结论是 logrogate 这个比较靠谱?先收藏先,马上会用到了

我们使用的是 logrotate

这个问题正好我前几天也碰到,我现在在用这个 GEM,还不错,缺省的配置就是 rolling file:

https://github.com/TwP/logging-rails

logrogate 比较靠谱,一直在用,而且会自动压缩打包。之前用 Rails 自带的切换,每次到零点都会切换失败导致 Rails 进程僵死!

#3 楼 @zmbacker 意思是不配置 config.logger 就不会自己分割了把。。请问如果用 unicorn 会自己分割么。。

#19 楼 @huacnlee 尝试了一下 logrogate+syslog_logger,但是发现用上 syslog_logger 以后,log 都没了。

config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

另外,logrogate 我这样配置

/opt/rails_apps/log_test/current/log/staging.log  {
        missingok
        nocompress
        daily
        copytruncate
        create
        ifempty
        rotate 3
        dateext
       olddir /tmp
        postrotate
                [ -f /opt/rails_apps/log_test/current/tmp/pids/unicorn.pid ] && su hzh -c " kill -USR1 `cat /opt/rails_apps/log_test/current/tmp/pids/unicorn.pid`"
        endscript
}

logrotate 强制执行了一下,没在/tmp 目录下找到分割的日志

#23 楼 @huacnlee 有参数 copytruncate 可以用吧,能继续产生 Log,不用配置 Unicorn

#25 楼 @quakewang copytruncate 不会出现文件句柄问题的。原理就是拷贝内容到备份文件,然后 truncate 文件。中间可能出现部分日志丢失的状况。。

copytruncate Truncate the original log file to zero size in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.

找到一篇关于 logrotate 简单实用的文章, 使用 logrotate 定期整理 Rails Log 檔案

lgcjwt [该话题已被删除] 提及了此话题。 06月01日 21:12
lgcjwt Ruby 原生日志分割已经解决多进程问题? 提及了此话题。 06月01日 22:49
需要 登录 后方可回复, 如果你还没有账号请 注册新账号