Réponses:
Vous pouvez créer vous-même un objet Logger à partir de n'importe quel modèle. Passez simplement le nom du fichier au constructeur et utilisez l'objet comme les Rails habituels 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
Ici, j'ai utilisé un attribut de classe pour mémoriser l'enregistreur. De cette façon, il ne sera pas créé pour chaque objet User qui est créé, mais vous n'êtes pas obligé de le faire. Rappelez-vous également que vous pouvez injecter la my_logger
méthode directement dans la ActiveRecord::Base
classe (ou dans une superclasse de votre choix si vous n'aimez pas trop les patchs de singe) pour partager le code entre les modèles de votre application.
User.logger = Logger.new(STDOUT)
changé toute la journalisation pour tous les modèles. Eh bien, ça a changéActiveRecord::Base.logger
my_logger
dans application_controller.rb
.
Mettre à jour
J'ai créé un bijou basé sur la solution ci-dessous, appelé multi_logger . Faites simplement ceci dans l'initialiseur:
MultiLogger.add_logger('post')
et appeler
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
et vous avez terminé.
Si vous souhaitez le coder vous-même, voir ci-dessous:
Une solution plus complète serait de placer les éléments suivants dans votre répertoire lib/
ou config/initializers/
.
L'avantage est que vous pouvez configurer le formateur pour qu'il préfixe automatiquement les horodatages ou la gravité aux journaux. Ceci est accessible de n'importe où dans Rails et semble plus net en utilisant le modèle 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
#{$$}
pour?
Une option décente qui fonctionne pour moi consiste simplement à ajouter une classe assez simple à votre app/models
dossier, telle queapp/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
puis dans votre contrôleur, ou vraiment presque partout où vous pouvez référencer la classe d'un modèle à partir de votre application de rails, c'est-à-dire partout où vous pouvez faire Post.create(:title => "Hello world", :contents => "Lorum ipsum");
ou quelque chose de similaire, vous pouvez vous connecter à votre fichier personnalisé comme celui-ci
MyLog.debug "Hello world"
Définissez une classe de journalisation dans (par exemple) 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
initialisez le logger dans (disons) config / initializers / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
N'importe où dans votre application, vous pouvez vous connecter avec:
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
Je suggérerais d'utiliser la gemme Log4r pour la journalisation personnalisée. Citant la description de sa page:
Log4r est une bibliothèque de journalisation complète et flexible écrite en Ruby pour une utilisation dans les programmes Ruby. Il comprend un système de journalisation hiérarchique de n'importe quel nombre de niveaux, des noms de niveau personnalisés, l'héritage de l'enregistreur, plusieurs destinations de sortie par événement de journal, le suivi de l'exécution, le formatage personnalisé, la sécurité des threads, la configuration XML et YAML, etc.
Le framework Logging, avec son nom trompeusement simple, a la sophistication dont vous rêvez!
Suivez les instructions très courtes des rails de journalisation pour commencer à filtrer le bruit, à recevoir des alertes et à choisir la sortie d'une manière fine et de haut niveau.
Tapotez-vous dans le dos lorsque vous avez terminé. Journal de roulement, tous les jours. Ça vaut le coup pour ça seul.
User.logger = Logger.new(STDOUT)
ou où vous souhaitez vous connecter. De la même manière,ActiveRecord::Base.logger = Logger.new(STDOUT)
changera toute la journalisation pour tous les modèles.