gpt4 book ai didi

ruby-on-rails - 使用 Ruby 标准 Logger 每天只创建一个日志

转载 作者:数据小太阳 更新时间:2023-10-29 07:11:37 25 4
gpt4 key购买 nike

我正在使用 ruby​​ 标准记录器,我想要每天轮换一次,所以在我的代码中我有:

Logger.new("#{$ROOT_PATH}/log/errors.log", 'daily')  

它运行完美,但它创建了两个文件 errors.log.20130217errors.log.20130217.1

如何强制它每天只创建一个文件?

最佳答案

您的代码对于长时间运行的应用程序是正确的。

发生的事情是您在给定的一天多次运行代码。

第一次运行时,Ruby 会创建一个日志文件“errors.log”。

当日期改变时,Ruby 将文件重命名为“errors.log.20130217”。

但不知何故你再次运行代码,也许你正在运行两个使用相似代码的应用程序(或进程,或工作人员,或线程),并且你的记录器看到文件名“errors.log.20130217”已经存在.

您的记录器不想破坏该文件,但仍需要将“errors.log”重命名为日期,因此记录器创建了一个不同的文件名“errors.log.20130217.1”

要解决此问题,只需运行一次您的代码。

如果您正在运行多个名为“foo”和“bar”的应用,则使用“foo-errors.log”和“bar-errors.log”等日志文件名。或者,如果您使用多个工作人员,请为每个工作人员提供自己的日志文件名(例如,通过使用工作人员的进程 ID、工作人员池数组索引,或者您跟踪工作人员的任何方式)。

如果您真的想使用 Ruby 记录器解决这个问题,您需要覆盖记录器#shift_log_period,这样它就不会选择“.1”后缀。您可以将 Logger 子类化并编写您磨损的#shift_log_period 来检测是否存在该日期的现有日志文件,如果存在,则使用它而不是重命名文件。

这是来自记录器的代码:

def shift_log_period(period_end)
postfix = period_end.strftime("%Y%m%d") # YYYYMMDD
age_file = "#{@filename}.#{postfix}"
if FileTest.exist?(age_file)
# try to avoid filename crash caused by Timestamp change.
idx = 0
# .99 can be overridden; avoid too much file search with 'loop do'
while idx < 100
idx += 1
age_file = "#{@filename}.#{postfix}.#{idx}"
break unless FileTest.exist?(age_file)
end
end
@dev.close rescue nil
File.rename("#{@filename}", age_file)
@dev = create_logfile(@filename)
return true

没有解决方案(据我所知)使用 Ruby 记录器及其内置旋转器来同时管理由多个应用程序(也称为工作程序、进程、线程)写入的日志。这是因为每个应用程序都有自己的日志文件句柄。

或者,使用任何好的日志轮转器工具,例如 Tin Man 用户在问题评论中建议的 logrotate:http://linuxcommand.org/man_pages/logrotate8.html

一般来说,logrotate 将是您最好的选择恕我直言。

关于ruby-on-rails - 使用 Ruby 标准 Logger 每天只创建一个日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14927418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com