Antworten:
Sie können ein Logger-Objekt in jedem Modell selbst erstellen. Übergeben Sie einfach den Dateinamen an den Konstruktor und verwenden Sie das Objekt wie die üblichen 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
Hier habe ich ein Klassenattribut verwendet, um den Logger auswendig zu lernen. Auf diese Weise wird es nicht für jedes einzelne Benutzerobjekt erstellt, das erstellt wird, aber Sie müssen dies nicht tun. Denken Sie auch daran, dass Sie die my_logger
Methode direkt in die ActiveRecord::Base
Klasse (oder in eine eigene Superklasse, wenn Sie nicht zu viel Affen-Patches möchten) einfügen können, um den Code zwischen den Modellen Ihrer App zu teilen.
User.logger = Logger.new(STDOUT)
Die gesamte Protokollierung für alle Modelle wurde geändert. Nun, es hat sich geändertActiveRecord::Base.logger
my_logger
in application_controller.rb
.
Aktualisieren
Ich habe ein Juwel basierend auf der folgenden Lösung namens multi_logger erstellt . Tun Sie dies einfach im Initialisierer:
MultiLogger.add_logger('post')
und Ruf an
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
und du bist fertig.
Wenn Sie es selbst codieren möchten, siehe unten:
Eine vollständigere Lösung wäre, Folgendes in Ihr lib/
oder config/initializers/
Verzeichnis zu legen .
Der Vorteil besteht darin, dass Sie den Formatierer so einrichten können, dass Zeitstempel oder Schweregrade automatisch in die Protokolle eingefügt werden. Dies ist von überall in Rails zugänglich und sieht mithilfe des Singleton-Musters besser aus.
# 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
#{$$}
?
Eine anständige Option, die für mich funktioniert, besteht darin, Ihrem app/models
Ordner eine ziemlich einfache Klasse hinzuzufügen, zapp/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
dann in Ihrem Controller oder wirklich fast überall dort, wo Sie in Ihrer Rails-App auf die Klasse eines Modells verweisen können, dh überall dort, wo Sie dies tun können Post.create(:title => "Hello world", :contents => "Lorum ipsum");
oder ähnliches, können Sie sich in Ihrer benutzerdefinierten Datei wie dieser anmelden
MyLog.debug "Hello world"
Definieren Sie eine Logger-Klasse in (sagen wir) 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
Initialisieren Sie den Logger in (sagen wir) config / initializers / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
Überall in Ihrer App können Sie sich anmelden mit:
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
Ich würde vorschlagen, Log4r gem für die benutzerdefinierte Protokollierung zu verwenden. Zitat Beschreibung von seiner Seite:
Log4r ist eine umfassende und flexible Protokollierungsbibliothek, die in Ruby zur Verwendung in Ruby-Programmen geschrieben wurde. Es verfügt über ein hierarchisches Protokollierungssystem mit einer beliebigen Anzahl von Ebenen, benutzerdefinierten Ebenennamen, Logger-Vererbung, mehreren Ausgabezielen pro Protokollereignis, Ausführungsverfolgung, benutzerdefinierter Formatierung, Thread-Sicherheit, XML- und YAML-Konfiguration und mehr.
Das Logging-Framework mit seinem täuschend einfachen Namen hat die Raffinesse, nach der Sie sich sehnen!
Befolgen Sie die sehr kurzen Anweisungen von Logging-Rails , um Rauschen herauszufiltern, Warnungen zu erhalten und die Ausgabe feinkörnig und auf hoher Ebene auszuwählen.
Klopfen Sie sich auf den Rücken, wenn Sie fertig sind. Täglich Holzrollen. Allein dafür lohnt es sich.
User.logger = Logger.new(STDOUT)
oder wo immer Sie sich anmelden möchten. Auf die gleiche WeiseActiveRecord::Base.logger = Logger.new(STDOUT)
wird die gesamte Protokollierung für alle Modelle geändert.