Risposte:
È possibile creare un oggetto Logger da soli all'interno di qualsiasi modello. Basta passare il nome del file al costruttore e usare l'oggetto come i soliti 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
Qui ho usato un attributo di classe per memorizzare il logger. In questo modo non verrà creato per ogni singolo oggetto utente che viene creato, ma non è necessario farlo. Ricorda anche che puoi inserire il my_loggermetodo direttamente nella ActiveRecord::Baseclasse (o in una tua superclasse se non ti piace scimmiottare troppo la patch) per condividere il codice tra i modelli della tua app.
User.logger = Logger.new(STDOUT)ha cambiato tutta la registrazione per tutti i modelli. Bene, è cambiatoActiveRecord::Base.logger
my_loggerin application_controller.rb.
Aggiornare
Ho creato un gioiello basato sulla soluzione di seguito, chiamata multi_logger . Basta fare questo nell'inizializzatore:
MultiLogger.add_logger('post')
e chiama
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
e il gioco è fatto.
Se vuoi codificarlo tu stesso, vedi sotto:
Una soluzione più completa sarebbe quella di inserire quanto segue nel tuo lib/ o config/initializers/directory.
Il vantaggio è che è possibile impostare il formattatore in modo da aggiungere automaticamente il prefisso ai timestamp o alla gravità. Questo è accessibile da qualsiasi punto di Rails e sembra più ordinato usando il modello 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
#{$$}?
Un'opzione decente che funziona per me è semplicemente aggiungere una classe abbastanza semplice alla tua app/modelscartella comeapp/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
quindi nel tuo controller o quasi ovunque tu possa fare riferimento alla classe di un modello dall'app Rails, ovvero ovunque tu possa fare Post.create(:title => "Hello world", :contents => "Lorum ipsum");o qualcosa di simile puoi accedere al tuo file personalizzato come questo
MyLog.debug "Hello world"
Definire una classe logger in (diciamo) 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
inizializza il logger in (diciamo) config / initializer / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
Ovunque nella tua app, puoi accedere con:
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
Suggerirei di utilizzare Log4r gem per la registrazione personalizzata. Citando la descrizione dalla sua pagina:
Log4r è una libreria di registrazione completa e flessibile scritta in Ruby per l'uso nei programmi Ruby. È dotato di un sistema di registrazione gerarchico di qualsiasi numero di livelli, nomi di livello personalizzati, eredità del logger, destinazioni di output multiple per evento di registro, traccia di esecuzione, formattazione personalizzata, sicurezza dei thread, configurazione XML e YAML e altro ancora.
Il framework di registrazione, con il suo nome ingannevolmente semplice, ha la raffinatezza che brami!
Seguire le istruzioni molto brevi delle guide di accesso per iniziare a filtrare il rumore, ricevere avvisi e scegliere l'output in modo dettagliato e di alto livello.
Pat te sulla schiena quando hai finito. Log-rolling, tutti i giorni. Ne vale la pena da solo.
User.logger = Logger.new(STDOUT)o ovunque si desidera accedere. Allo stesso modo,ActiveRecord::Base.logger = Logger.new(STDOUT)cambierà tutta la registrazione per tutti i modelli.