我帮助维护一个Rails网站。它在Solaris Sparc机器上运行JRuby 1.5.5,Rails 2.3.10。我遇到了与日志有关的问题。
为了阻止我们的日志文件变得过大并填满磁盘,我们正在使用内置于Logger类的日志转换。在config / environments / production.rb中,我们有:
config.logger = Logger.new(config.log_path, 10, 100.megabyte)
当日志文件达到100兆字节时应该旋转日志文件,并且只保留10个文件。
问题是双重的:Rails没有正确地旋转日志,并且它保持打开旧的日志文件以写入它 - 但它写的只是一些请求的重复内容。所以,如果我ls -l log
,我会看到类似的事情:
-rw-r--r-- 83040892 Oct 4 15:07 production.log
-rw-r--r-- 3303158664 Oct 4 15:07 production.log.0
-rw-r--r-- 104857616 Oct 2 23:13 production.log.1
-rw-r--r-- 104857618 Oct 1 17:12 production.log.2
注意最近循环的日志如何仍然打开并仍在写入(运行pfiles
确认Rails服务器仍然有三个日志文件句柄)。另请注意,它在两天内达到了3千兆字节,通常我们每天可以达到100千兆字节。这是因为它充满了重复的请求。我不能轻易地将它粘贴在这里,但是日志充满了10月3日18:50(相信是日志旋转点)的相同1000行请求,一遍又一遍地打印。根据过去的经验,日志文件将继续填充这些重复的内容,直到磁盘填满。
日志转换/ Rails日志记录是否破损? (我们的日志文件用法并不奇怪:我们不做任何直接日志记录,它只是来自Rails框架。)明显的下一步是尝试像logrotate,但如果Rails拒绝关闭旧的日志文件和我永远在给他们写垃圾,我怀疑它不会解决我的问题(因为日志永远不会被关闭,因此磁盘空间永远不会恢复)。
答案 0 :(得分:10)
症状似乎是一个旧日志文件仍在继续使用,尽管您已成功轮换日志。
原因很可能一个或多个Rails实例或线程仍在使用旧文件句柄。
解决方案是为了确保所有Rails实例在日志轮换后完全重启,因此它们都使用新文件句柄/名称。
使用logrotate 而不是config.logger来旋转日志!
我建议使用UNIX logrotate来轮换日志,而不是使用config.logger。
恕我直言,这是一个更好的解决方案,更可靠,您可以更好地控制日志轮换,并且您可以提供一些后轮换命令来重新启动Rails进程。 (通过logrotate的postrotate
或endscript
选项)
见:
http://www.opencsw.org/packages/logrotate/(适用于Solaris的logrotate包)
http://www.thegeekstuff.com/2010/07/logrotate-examples/(带示例的logrotate教程)
http://linux.die.net/man/8/logrotate
你能使用Unicorn吗? - Unicorn内置支持通过USR1信号重新打开应用程序中的所有日志文件 - 这允许logrotate以原子方式旋转文件... - Unicorn跟踪并重新启动它的工作人员!您可以在日志轮换后终止工作,Unicorn将重新启动它们,确保它们使用新的日志文件。
参见:https://github.com/blog/517-unicorn(Unicorn优于Mongrel的许多优点)
如果您使用的是Mongrel ,则无法切换到Unicorn:
使用logrotate,并通过postrotate
选项重新启动Mongrels。
希望这会有所帮助..
答案 1 :(得分:2)
在处理Rails日志文件时,我总是使用平台的日志轮换机制。遵循http://www.nullislove.com/2007/09/10/rotating-rails-log-files/的建议,因为我也从http://overstimulate.com/articles/logrotate-rails-passenger运行Passenger。
第一种方法使用logrotate copytruncate
方法创建新的日志文件,因此仍然具有句柄的进程将始终写入当前日志文件。
在服务器上检查的其他事项包括:
答案 2 :(得分:2)
尼尔,
我不知道这是否适用于您的特定情况,但我遇到了类似的问题,我想我只是解决了它。就我而言,我有两个症状。第一个是和你一样的问题 - 我的日志轮换很麻烦......特别是,production.log.1文件保持打开状态,并且生产日志也正在登录时正在进行记录。第二个症状是日志文件所有权和组成员身份将不断更改为root。 My Rails应用程序是通过Capistrano部署的,使用'部署者'用户,因此每当应用程序尝试写入不再由部署者拥有的日志文件时,我都会收到各种各样的错误。
我很尴尬地说我花了多长时间才意识到这两个问题的原因是什么。在某个地方,我用应用程序的crontab 作为root 更新了cron。这一定是在我在命令提示符处搞乱时...如果我刚刚通过Capistrano保留了我的部署配方,我就不会无意中这样做了。在任何情况下,我终于查看了/ var / spool / cron / crontabs,我发现了我的crontab文件的两个副本...一个用于部署者,一个用于root用户。因此,cron为我的应用程序启动的进程正在重复 - 一个在部署程序下运行,另一个在根目录下运行。这是第二个搞砸了。一旦我删除了root的crontab,一切都会更好。
一些警告:在我的设置中,root的crontab中没有与应用程序无关的任务,即它与deployer的crontab完全相同...所以删除它对我没有任何副作用。此外,我的服务器正在运行Ubuntu ...你的crontabs的路径可能会有所不同。
希望有所帮助。
答案 3 :(得分:0)
我想你忘记了's',以兆字节为单位 或者改为使用类似的东西
config.logger = Logger.new(config.log_path, 10, 102400)
同时查看此链接非常有帮助