Câu trả lời:
Bạn có thể tự tạo một đối tượng Logger từ bên trong bất kỳ mô hình nào. Chỉ cần chuyển tên tệp cho hàm tạo và sử dụng đối tượng như Rails thông thường 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
Ở đây tôi đã sử dụng một thuộc tính lớp để ghi nhớ logger. Bằng cách này, nó sẽ không được tạo cho mọi đối tượng Người dùng duy nhất được tạo, nhưng bạn không bắt buộc phải làm điều đó. Cũng cần nhớ rằng bạn có thể đưa my_logger
phương thức trực tiếp vào ActiveRecord::Base
lớp (hoặc vào một số siêu lớp của riêng bạn nếu bạn không muốn vá khỉ quá nhiều) để chia sẻ mã giữa các mô hình ứng dụng của bạn.
User.logger = Logger.new(STDOUT)
thay đổi tất cả các bản ghi cho tất cả các mô hình. Chà, nó đã thay đổiActiveRecord::Base.logger
my_logger
vào application_controller.rb
.
Cập nhật
Tôi đã tạo ra một viên ngọc dựa trên giải pháp bên dưới, được gọi là multi_logger . Chỉ cần làm điều này trong trình khởi tạo:
MultiLogger.add_logger('post')
và gọi
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
và bạn đã hoàn thành.
Nếu bạn muốn tự viết mã, xem bên dưới:
Một giải pháp đầy đủ hơn sẽ là đặt những thứ sau đây trong thư mục lib/
hoặc config/initializers/
thư mục của bạn .
Lợi ích là bạn có thể thiết lập trình định dạng thành dấu thời gian tiền tố hoặc mức độ nghiêm trọng đối với nhật ký. Điều này có thể truy cập từ bất cứ nơi nào trong Rails và trông gọn gàng hơn bằng cách sử dụng mẫu singleton.
# 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
#{$$}
?
Một tùy chọn phù hợp với tôi là chỉ cần thêm một lớp khá đơn giản vào app/models
thư mục của bạn, chẳng hạn như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
sau đó trong bộ điều khiển của bạn hoặc thực sự gần như bất cứ nơi nào bạn có thể tham chiếu lớp của một mô hình từ trong ứng dụng rails của mình, tức là bất cứ nơi nào bạn có thể làm Post.create(:title => "Hello world", :contents => "Lorum ipsum");
hoặc một cái gì đó tương tự bạn có thể đăng nhập vào tệp tùy chỉnh của mình như thế này
MyLog.debug "Hello world"
Xác định một lớp logger trong (giả sử) ứng dụng / mô hình / 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
khởi tạo logger trong (nói) config / khởi tạo / Special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
Bất cứ nơi nào trong ứng dụng của bạn, bạn có thể đăng nhập bằng:
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
Tôi sẽ đề nghị sử dụng đá quý Log4r để đăng nhập tùy chỉnh. Trích dẫn mô tả từ trang của nó:
Log4r là một thư viện ghi nhật ký toàn diện và linh hoạt được viết bằng Ruby để sử dụng trong các chương trình Ruby. Nó có một hệ thống ghi nhật ký phân cấp của bất kỳ số cấp độ nào, tên cấp độ tùy chỉnh, kế thừa logger, nhiều đích đầu ra cho mỗi sự kiện nhật ký, theo dõi thực thi, định dạng tùy chỉnh, safteyness luồng, cấu hình XML và YAML, v.v.
Khung Logging, với cái tên đơn giản mang tính giả dối, có sự tinh tế mà bạn khao khát!
Thực hiện theo các hướng dẫn rất ngắn về đường ray đăng nhập để bắt đầu lọc tiếng ồn, nhận thông báo và chọn đầu ra theo cách chi tiết và cao cấp.
Hãy vỗ nhẹ vào lưng khi bạn đã hoàn thành. Đăng nhập, hàng ngày. Đáng giá cho điều đó một mình.
User.logger = Logger.new(STDOUT)
hoặc bất cứ nơi nào bạn muốn đăng nhập. Theo cùng một cách,ActiveRecord::Base.logger = Logger.new(STDOUT)
sẽ thay đổi tất cả các bản ghi cho tất cả các mô hình.