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 天分割一个
差了好多地方,看起来他们也是这么配置的
我之前的做法是 rails 不设置分割日志
而在系统中用 logrotate 或者其他的日志管理工具进行分割或其它维护操作
一般来说是可以很稳定运行的
个人认为日志管理属于系统范畴。之前我也尝试过 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 就可以啦
Heroku 的 12factor 关于日志的做法我比较喜欢,应用本身不处理日志的存储、分割等,直接输出到标准输出,用 fluent 或 logplex 集中处理日志。 这不仅是理论,实际上 Heroku 就是这么干的。slideshare.net 也是用的这个。 今天在 twitter 上还看到 matz 推荐 fluentd 了。。
日志 让应用程序的行为变得透明。在基于服务器的运行环境中,通常日志被写到磁盘里德文件(日志文件)里;但这不是唯一的输出格式。
日志是事件流的聚合。按照时间顺序把所有运行的进程和后台服务的输出收集起来。原始形态的日志通常是一行(尽管异常的堆栈信息可能有多行)记录一件事的文本。日志没有确定的开始和结束,但会随着应用的运行一直流动。
遵循“Web 开发十二军规”的应用本身从不考虑如何切分或存储输出的事件流。
应用本身不应该考虑如何写或处理日志文件。而是每个运行的进程把事件流输出到标准输出(stdout)
。在本地开发环境,开发者通过观察终端里的事件流来监视应用的行为。
在预发布或生产环境中,每个进程的事件流都会被运行环境捕获,并将其他输出流整理在一起,然后一起发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档目的对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。开源工具 (比如 Logplex 和 Fluent) 就是这个用途。
这些事件流可以输出至文件,或者使用 tail 工具在终端实时观察。最重要的,输出流可以被发送到像Splunk这样的索引分析系统。或像Hadoop/Hive这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括:
查找过去的特别事件。
图形化一个大规模的趋势(比如每分钟处理的请求量)
根据自定义的条件实时激活警报(比如每分钟的报错超过某个警戒线)
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
我的是跑任务,这样如果想发到别的服务器上也可以
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 也行啊
/data/www/ruby-china/current/log/production.log {
weekly
missingok
rotate 12
compress
dateext
delaycompress
lastaction
pid=/data/www/ruby-china/current/tmp/pids/unicorn.pid
sudo test -s $pid && sudo kill -USR1 "$(cat $pid)"
endscript
}
今天才配置上,已经测试了,靠谱
#22 楼 @quakewang USR1 是告诉 unicorn 重新加载日志文件,因为 logrogate 会把 production.log 移走
@huacnlee 前面都懂,那个脚本里面我没有找到 pid=/data/www/ruby-china/current/tmp/pids/nginx.pid,用 nginx 该怎么写 - -
这个问题正好我前几天也碰到,我现在在用这个 GEM,还不错,缺省的配置就是 rolling file:
#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 目录下找到分割的日志
#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.