Ruby on Rails 生产日志轮换

186

如何在生产环境的Ruby on Rails应用程序中实现最佳的日志轮换方式?

是在托管服务器上使用logrotate,还是在初始化应用程序中从日志记录器使用一组选项?


我看到这个问题已经有了答案,但我想问一下你的环境是什么。我自己使用 syslog + logrotate 方法,但显然环境的种类(是否专用、共享;托管的是哪种 *ix 操作系统等)会对此产生一些影响。 - ylluminate
6个回答

210

选项1:syslog + logrotate

您可以配置Rails使用系统日志工具。

config/environments/production.rb中有一个例子。

# Use a different logger for distributed setups
config.logger = SyslogLogger.new

这样,你可以记录到系统日志,并可以使用默认的logrotate工具来轮换日志。

选项2:普通Rails日志+logrotate

另一个选项是简单地配置logrotate以拾取rails留下的日志。 在Ubuntu和Debian上,例如,这将在名为/etc/logrotate.d/rails_example_com的文件中。

/path/to/rails.example.com/tmp/log/*.log {
    weekly
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    copytruncate
}

根据以下建议,在Rails中建议使用copytruncate,以避免需要重新启动Rails应用程序。

编辑:根据评论,删除了“sharedscripts/endscript”,因为它们在这里没有被使用并会引起问题。同时根据评论建议,删除了create 640 root adm


3
为了使用logrotate,config/environments/production.rb文件中的"config.logger = SyslogLogger.new"这一行应该保持注释还是取消注释? - robertwbradford
4
如果使用logrotate解决方案,则值得关注@amit-saxena的答案--建议使用copytruncate替代create指令。 - Tom Harrison
3
使用copytruncate时,create选项没有效果,因此您应该从示例中将其删除。 - Michaël Witrant
5
你可能还需要添加一行 su your_rails_user your_rails_group,其中包括你的日志文件所有者和组(即Rails/Passenger进程的日志文件),否则logrotate可能会报错权限问题。(注意:这句话有些括号内内容是疑问句,表示不确定性,应该翻译成相应的语气)。 - oseiskar
2
测试日志轮转文件是个好主意,这样你就能看到它是否会抛出任何错误:sudo logrotate -f /etc/logrotate.d/rails_example_com。通过这种方式,我发现我必须像oseiskar建议的那样添加 su rails_user rails_user_group - Bram
显示剩余7条评论

58
如果您正在使用logrotate,则可以通过在/etc/logrotate.d/目录中放置conf文件来选择以下选项之一。
# Rotate Rails application logs based on file size
# Rotate log if file greater than 20 MB
/path/to/your/rails/applicaton/log/*.log {
    size=20M
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    copytruncate
}

或者

# Rotate Rails application logs weekly
/path/to/your/rails/applicaton/log/*.log {
  weekly
  missingok
  rotate 52
  compress
  delaycompress
  notifempty
  copytruncate
}

请注意,copytruncate会备份当前日志并清除日志文件以继续写入。另一种选择是使用create,它将通过重命名当前文件并创建一个与旧文件同名的新日志文件来执行轮换。

我强烈建议您使用copytruncate,除非您知道需要使用create。原因是Rails可能仍然指向旧的日志文件,即使它的名称已更改,可能需要重新启动才能找到新的日志文件。而copytruncate避免了这个问题,它保持相同的文件作为活动文件。


但是每次 logrotate 运行时,我不应该重新启动 Rails 吗? - lzap
2
在创建副本后,就地截断原始日志文件,而不是移动旧的日志文件并可选地创建新的日志文件。当某些程序无法关闭其日志文件并可能继续永远写入(追加)到先前的日志文件时,可以使用它。请注意,在复制文件和截断文件之间有一个非常短的时间片段,因此可能会丢失一些日志数据。当使用此选项时,create选项将无效,因为旧的日志文件保持在原位。 - lzap
1
如果您使用的是copytruncate,那么您不需要重新启动Rails,因为它仍然指向相同的日志文件。 - amit_saxena
配置是否要求您指定何时轮换日志?例如“每周”或“大小=20M”?或者,如果您只想手动运行logrotate,是否可以省略它? - Damainman
1
我不确定我是否正确理解了你的问题,但是你需要为自动日志轮换指定一个标准。如果你不想让它自动运行,就不要把文件放在 /etc/logrotate.d/ 目录中,将其放在其他地方。然后,你可以通过指定配置文件位置手动运行 logrotate --force $CONFIG_FILE - amit_saxena

37

对于Rails 5,这是我必须做的来限制日志大小并且不改变控制台中的服务器输出:

根据文档,如果你想要限制日志文件夹的大小,在你的环境文件('development.rb'/'production.rb')中添加以下内容。

config.logger = ActiveSupport::Logger.new(config.paths['log'].first, 1, 50 * 1024 * 1024)

使用这个方法,您的日志文件大小将永远不会超过50Mb。您可以根据自己的喜好更改大小。第二个参数中的“1”表示将保留1个历史日志文件,因此您最多可以拥有100Mb的日志——当前的日志和之前的50Mb块。

此解决方案的来源


2
第一个参数是文件名,简单来说,即“log/development.log”。因此,我更喜欢更长但透明的方式。我会使用Rails.root.join('log', "#{Rails.env}.log")而不是config.paths['log'].first - Mikhail Chuprynski
1
@ZiaUlRehmanMughal 是的,它可以在Rails 4中工作。我正在使用Rails 4.2.3,并配置如下:config.logger = ActiveSupport :: Logger.new(config.log_file,1,20 * 1024 * 1024) - ThienSuBS
2
为了让阅读更加容易,值得一提的是,您可以依赖于ActiveSupport字节扩展:50.megabytes50 * 1024 * 1024相同,但更容易理解。有关更多详细信息,请参见ActiveSupport核心扩展 - Pierre-Adrien
1
又一次通过谷歌搜索到这里了(程序员的生活 :D)。我在想我们是否可以配置这行代码来旋转日志文件夹中的所有日志文件?显然,这行代码只会旋转第一行。 - Zia Ul Rehman Mughal
请注意,这将仅旋转您的日志/production.log文件,因为Rails.application.config.paths ['log'] .first恰好返回此文件。 - valachi

8

对于Rails 5,如果您想进行每日日志轮换,您只需要这样做:

  config.logger = ActiveSupport::Logger.new(config.paths['log'].first, shift_age = 'daily')

根据文档,可以使用dailyweeklymonthly

5

对于每一个日志:Rails 日志,Rpush 日志,...

您可以在服务的配置文件中像这样使用:

 config.log_file = 'log/rpush.log'
 config.logger = ActiveSupport::Logger.new(config.log_file, 1, 20.megabytes)

意思是:在分割后只保存一个以前的日志文件。主要日志大小永远不超过20 MB。

-9

通过在我的environments/production.rb文件中使用rails logglier,可以将日志发送到loggly。 rails版本为4.1.0

RailsApplication::Application.configure do
require 'logglier'
config.logger = Logglier.new(<https://logs-01.loggly.com/inputs/inputkey>)
log.info("hello from logglier")
end

Rails的版本是4.1.0,Ruby的版本是2.1.1。 - riya khana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接