Answers:
您可以从任何模型内部自己创建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属性来记录记录器。这样,就不会为创建的每个用户对象都创建它,但是您不需要这样做。还要记住,您可以将my_logger
方法直接注入到ActiveRecord::Base
类中(如果您不想过多地修补猴子,则可以注入到自己的某些超类中),以在应用程序的模型之间共享代码。
User.logger = Logger.new(STDOUT)
更改了所有模型的所有日志记录。好吧,它改变了ActiveRecord::Base.logger
my_logger
,对我的控制器做了几乎相同的操作application_controller.rb
。
更新资料
我根据以下解决方案制作了一个宝石,称为multi_logger。只需在初始化程序中执行以下操作:
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
#{$$}
用
一个对我有用的不错的选择是将一个简单的类添加到您的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"
在(例如)app / models / 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 / initializers / 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")
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
User.logger = Logger.new(STDOUT)
或在任何要登录的地方进行记录。以相同的方式,ActiveRecord::Base.logger = Logger.new(STDOUT)
将更改所有模型的所有日志记录。