Ruby on Rails 生产日志轮换

Posted

技术标签:

【中文标题】Ruby on Rails 生产日志轮换【英文标题】:Ruby on Rails production log rotation 【发布时间】:2011-06-20 12:17:32 【问题描述】:

在 Ruby on Rails 生产应用程序上启用日志轮换的最佳方法是什么?

是通过在托管服务器上使用 logrotate 还是在从应用程序初始化记录器时使用一组选项?

【问题讨论】:

我看到已经有答案了,但我想问一下你的环境是什么。我自己使用 syslog + logrotate 方法,但显然环境类型(无论是专用的、共享的;托管的是哪种 *ix 操作系统,还是另一种等)在这里会有一些影响。 【参考方案1】:

选项 1:syslog + logrotate

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

config/environments/production.rb中的一个示例。

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

这样,您可以登录到 syslog,并且可以使用默认的 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

【讨论】:

为了使用 logrotate,config/environments/production.rb 中的 "config.logger = SyslogLogger.new" 行是否应该被注释掉,还是应该取消注释? 它应该保持注释掉,以便日志文件写入(例如):/var/www/myrailsapp/current/log/production.log 如果使用logrotate 解决方案,值得@amit-saxena 的回答——建议在create 指令上使用copytruncate 当您使用copytruncate 时,create 无效,因此您应该将其从示例中删除 您可能还需要添加 su your_rails_user your_rails_group 行以及日志文件的所有者和组(即 Rails/Passenger 进程的那些)或(最新版本?)logrotate 可能会抱怨权限。【参考方案2】:

如果您使用的是 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,除非您知道需要创建。原因是 Rails 可能仍然指向旧的日志文件,即使它的名称已更改,它们可能需要重新启动才能找到新的日志文件。 copytruncate 通过保留与活动文件相同的文件来避免这种情况。

【讨论】:

但是我不应该在每次运行 logrotate 时重新启动 rails 吗? 创建副本后在原地截断原始日志文件,而不是移动旧日志文件并选择性地创建新日志文件,当某些程序无法被告知关闭其日志文件和因此可能会永远继续写入(附加)到前一个日志文件。请注意,复制文件和截断文件之间的时间片非常短,因此可能会丢失一些日志数据。使用此选项时,create 选项将不起作用,因为旧日志文件保留在原位。 如果你使用的是copytruncate,你不需要重启rails,因为它仍然指向同一个日志文件。 配置是否要求您说明何时轮换日志?例如“每周”或“size=20M”?或者如果您只想手动运行 logrotate,您可以省略它吗? 我不确定我是否正确理解了您的问题,但您需要指定自动日志轮换的标准。如果您不希望它是自动的,请不要将文件放在 /etc/logrotate.d/ 目录中,将其保存在其他位置。然后,您可以通过指定配置文件位置来手动运行logrotate --force $CONFIG_FILE【参考方案3】:

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

According to the documentation,如果您想限制日志文件夹的大小,请将其放入您的环境文件('development.rb'/'production.rb')中。

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

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

Source to this solution.

【讨论】:

第一个参数是文件名,简单来说就是'log/development.log'。所以我更喜欢更长但更透明的方式。而不是config.paths['log'].first我会放Rails.root.join('log', "#Rails.env.log") @ZiaUlRehmanMughal 是的,它适用于 Rails 4。我使用的是 Rails 4.2.3,配置如下:config.logger = ActiveSupport::Logger.new(config.log_file, 1, 20*1024*1024) 为了更容易阅读,值得一提的是,您可以依赖 ActiveSupport 字节扩展:50.megabytes50 * 1024 * 1024 相同,但更容易理解。有关详细信息,请参阅ActiveSupport core extensions。 经过一番谷歌搜索后再次来到这里(程序员生活:D)。我想知道我们是否可以将此行配置为轮换日志文件夹中的所有日志文件?显然这条线只会旋转第一行。 请注意,这只会轮换您的 log/production.log 文件,因为 Rails.application.config.paths['log'].first 会准确返回此文件【参考方案4】:

对于 Rails 5,如果你想要每日日志轮换,你只需要这个:

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

根据documentation,您可以使用dailyweeklymonthly

【讨论】:

【参考方案5】:

对于每个日志:Rails 日志,Rpush 日志,... 你可以在你的服务配置文件中这样使用:

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

意思是:拆分后只保存前一个日志文件。 主日志大小永远不会超过 20 MB。

【讨论】:

【参考方案6】:

在我的环境/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

以上是关于Ruby on Rails 生产日志轮换的主要内容,如果未能解决你的问题,请参考以下文章