如何在独立的日志文件中记录 Rails 中的内容?

在 Rails 中,我希望在不同的日志文件中记录一些信息,而不是标准的 development.log 或 production.log。我想从一个模型类中做这个日志记录。

85410 次浏览

您可以在任何模型中自己创建 Logger 对象。只需将文件名传递给构造函数,然后像通常的 Rails logger那样使用对象:

class User < ActiveRecord::Base
def my_logger
@@my_logger ||= Logger.new("#{Rails.root}/log/my.log")
end


def before_save
my_logger.info("Creating user with name #{self.name}")
end
end

在这里,我使用了一个 class 属性来制表日志记录器。这样就不会为每个创建的 User 对象创建它,但是您不需要这样做。还要记住,您可以将 my_logger方法直接注入到 ActiveRecord::Base类中(或者您自己的某个超类中,如果您不喜欢过多修补的话) ,以便在应用程序模型之间共享代码。

class Article < ActiveRecord::Base


LOGFILE = File.join(RAILS_ROOT, '/log/', "article_#{RAILS_ENV}.log")


def validate
log "was validated!"
end


def log(*args)
args.size == 1 ? (message = args; severity = :info) : (severity, message = args)
Article.logger severity, "Article##{self.id}: #{message}"
end


def self.logger(severity = nil, message = nil)
@article_logger ||= Article.open_log
if !severity.nil? && !message.nil? && @article_logger.respond_to?(severity)
@article_logger.send severity, "[#{Time.now.to_s(:db)}] [#{severity.to_s.capitalize}] #{message}\n"
end
message or @article_logger
end


def self.open_log
ActiveSupport::BufferedLogger.new(LOGFILE)
end


end

对我来说,一个不错的选择是添加一个相当普通的类到您的 app/models文件夹,如 app/models/my_log.rb

class MyLog
def self.debug(message=nil)
@my_log ||= Logger.new("#{Rails.root}/log/my.log")
@my_log.debug(message) unless message.nil?
end
end

然后在你的控制器,或者几乎任何你可以从你的 Rails 应用程序中引用模型类的地方,也就是任何你可以做 Post.create(:title => "Hello world", :contents => "Lorum ipsum");或类似的事情的地方,你可以像这样记录到你的定制文件

MyLog.debug "Hello world"

更新

我根据下面的解决方案做了一个 gem,叫做 多日志记录器:

MultiLogger.add_logger('post')

打电话

Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.

你就完了。

如果您想自己编写代码,请参阅下面的代码:


更完整的解决方案是将以下内容放在 lib/config/initializers/目录中。

这样做的好处是,可以将格式化程序设置为自动为日志添加时间戳或严重性的前缀。这可以从 Rails 的任何地方访问,并且通过使用单例模式看起来更整洁。

# Custom Post logger
require 'singleton'
class PostLogger < Logger
include Singleton


def initialize
super(Rails.root.join('log/post_error.log'))
self.formatter = formatter()
self
end


# Optional, but good for prefixing timestamps automatically
def formatter
Proc.new{|severity, time, progname, msg|
formatted_severity = sprintf("%-5s",severity.to_s)
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S")
"[#{formatted_severity} #{formatted_time} #{$$}] #{msg.to_s.strip}\n"
}
end


class << self
delegate :error, :debug, :fatal, :info, :warn, :add, :log, :to => :instance
end
end


PostLogger.error('hi')
# [ERROR 2012-09-12 10:40:15] hi

我建议使用 Log4r gem进行自定义日志记录:

Log4r 是用 Ruby 编写的一个全面而灵活的日志库,以供使用 它的特点是一个分层的日志系统,可以包含任意数量的 级别、自定义级别名称、记录器继承、多个输出目的地 每个日志事件,执行跟踪,自定义格式,线程安全性,XML 和 YAML 配置等等。

Logging 框架的名称看似简单,却具有您所渴望的复杂性!

按照非常简短的指示 伐木轨道开始过滤出噪音,获得警报,并选择输出在一个细粒度和高层次的方式。

当你完成的时候,拍拍自己的后背。每天滚木头。仅仅这一点就值得了。

这是我的自定义记录器:

class DebugLog
def self.debug(message=nil)
return unless Rails.env.development? and message.present?
@logger ||= Logger.new(File.join(Rails.root, 'log', 'debug.log'))
@logger.debug(message)
end
end
class Post < ActiveRecord::Base
def initialize(attributes)
super(attributes)
@logger = Logger.new("#{Rails.root}/log/post.log")
end


def logger
@logger
end


def some_method
logger.info('Test 1')
end
end


ps = Post.new
ps.some_method
ps.logger.info('Test 2')
Post.new.logger.info('Test 3')

在(比如) app/model/special _ log. rb 中定义一个日志记录器类:

class SpecialLog
LogFile = Rails.root.join('log', 'special.log')
class << self
cattr_accessor :logger
delegate :debug, :info, :warn, :error, :fatal, :to => :logger
end
end

在(比如) config/initializer/special _ log. rb 中初始化日志记录器:

SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal

在你的应用程序的任何地方,你都可以登录:

SpecialLog.debug("something went wrong")
# or
SpecialLog.info("life is good")