Jawaban:
Anda dapat membuat objek Logger sendiri dari dalam model apa pun. Cukup berikan nama file ke konstruktor dan gunakan objek seperti Rails biasa 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
Di sini saya menggunakan atribut class untuk memoize the logger. Dengan cara ini tidak akan dibuat untuk setiap objek Pengguna tunggal yang akan dibuat, tetapi Anda tidak diharuskan untuk melakukannya. Ingat juga bahwa Anda dapat menyuntikkan my_logger
metode secara langsung ke dalam ActiveRecord::Base
kelas (atau ke dalam superkelas Anda sendiri jika Anda tidak suka terlalu banyak menambal monyet) untuk membagikan kode di antara model aplikasi Anda.
User.logger = Logger.new(STDOUT)
mengubah semua pencatatan untuk semua model. Yah, itu berubahActiveRecord::Base.logger
my_logger
di application_controller.rb
.
Memperbarui
Saya membuat permata berdasarkan solusi di bawah ini, yang disebut multi_logger . Lakukan ini di penginisialisasi:
MultiLogger.add_logger('post')
dan telepon
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
dan kamu selesai.
Jika Anda ingin membuat kode sendiri, lihat di bawah:
Solusi yang lebih lengkap adalah dengan menempatkan yang berikut ini di direktori lib/
atau Anda config/initializers/
.
Keuntungannya adalah Anda dapat mengatur formatter untuk membuat awalan cap waktu atau tingkat keparahan ke log secara otomatis. Ini dapat diakses dari mana saja di Rails, dan terlihat lebih rapi dengan menggunakan pola tunggal.
# 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
#{$$}
?
Opsi yang layak yang berfungsi untuk saya adalah menambahkan kelas yang cukup sederhana ke app/models
folder Anda sepertiapp/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
kemudian di controller Anda, atau benar-benar hampir di mana saja Anda bisa mereferensikan kelas model dari dalam aplikasi rails Anda, yaitu di mana pun Anda bisa melakukan Post.create(:title => "Hello world", :contents => "Lorum ipsum");
atau sesuatu yang serupa Anda dapat masuk ke file kustom Anda seperti ini
MyLog.debug "Hello world"
Tentukan kelas logger di (katakanlah) 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
inisialisasi logger di (katakanlah) config / initializers / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
Di mana saja di aplikasi Anda, Anda dapat masuk dengan:
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
Saya akan menyarankan menggunakan permata Log4r untuk penebangan kustom. Mengutip deskripsi dari halamannya:
Log4r adalah perpustakaan logging komprehensif dan fleksibel yang ditulis dalam Ruby untuk digunakan dalam program Ruby. Ini fitur sistem pencatatan hierarkis sejumlah tingkat, nama tingkat kustom, warisan logger, beberapa tujuan output per peristiwa log, pelacakan eksekusi, pemformatan kustom, keselamatan thread, konfigurasi XML dan YAML, dan banyak lagi.
Kerangka Penebangan, dengan nama yang tampak sederhana, memiliki kecanggihan yang Anda idamkan!
Ikuti instruksi sangat singkat dari logging-rails untuk memulai menyaring kebisingan, mendapatkan peringatan, dan memilih output dengan cara yang halus dan tingkat tinggi.
Tepuk-tepuk diri Anda sendiri ketika Anda selesai. Log-rolling, setiap hari. Layak untuk itu saja.
User.logger = Logger.new(STDOUT)
atau ke mana pun Anda ingin masuk. Dengan cara yang sama,ActiveRecord::Base.logger = Logger.new(STDOUT)
akan mengubah semua pencatatan untuk semua model.