Respostas:
Você pode criar um objeto Logger de dentro de qualquer modelo. Apenas passe o nome do arquivo para o construtor e use o objeto como o Rails usual 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
Aqui eu usei um atributo de classe para memorizar o criador de logs. Dessa forma, ele não será criado para cada objeto Usuário criado, mas você não é obrigado a fazer isso. Lembre-se também de que você pode injetar o my_logger
método diretamente na ActiveRecord::Base
classe (ou em alguma superclasse de sua preferência, se você não gostar muito do patch do macaco) para compartilhar o código entre os modelos do seu aplicativo.
User.logger = Logger.new(STDOUT)
mudou todo o log para todos os modelos. Bem, isso mudouActiveRecord::Base.logger
my_logger
em application_controller.rb
.
Atualizar
Fiz uma gema com base na solução abaixo, chamada multi_logger . Basta fazer isso no inicializador:
MultiLogger.add_logger('post')
e ligar
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
e você terminou.
Se você deseja codificá-lo, veja abaixo:
Uma solução mais completa seria colocar o seguinte no seu diretório lib/
ou config/initializers/
.
O benefício é que você pode configurar o formatador para prefixar timestamps ou severity nos logs automaticamente. Isso pode ser acessado de qualquer lugar no Rails e fica mais limpo usando o padrão 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
#{$$}
?
Uma opção decente que funciona para mim é apenas adicionar uma classe bastante simples à sua app/models
pasta, comoapp/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
no controlador, ou quase em qualquer lugar em que você possa referenciar a classe de um modelo a partir do aplicativo rails, ou seja, em qualquer lugar que você possa fazer Post.create(:title => "Hello world", :contents => "Lorum ipsum");
ou algo semelhante, você poderá fazer logon no seu arquivo personalizado como este
MyLog.debug "Hello world"
Defina uma classe de criador de logs em (digamos) 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
inicialize o logger (digamos) config / initializers / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
Em qualquer lugar do seu aplicativo, você pode fazer login com:
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
Eu sugeriria o uso do Log4r gem para log personalizado. Citando a descrição de sua página:
O Log4r é uma biblioteca de registro abrangente e flexível, escrita em Ruby para uso em programas Ruby. Possui um sistema de registro hierárquico de qualquer número de níveis, nomes de níveis personalizados, herança do criador de log, vários destinos de saída por evento de log, rastreamento de execução, formatação personalizada, segurança de encadeamento, configuração XML e YAML e muito mais.
A estrutura de log, com seu nome enganosamente simples, tem a sofisticação que você deseja!
Siga as instruções muito curtas dos trilhos de registro para começar a filtrar o ruído, receber alertas e escolher a saída de maneira refinada e de alto nível.
Dê um tapinha nas costas quando terminar. Rolando log, diariamente. Vale a pena só por isso.
User.logger = Logger.new(STDOUT)
ou onde quer que você faça o logon. Da mesma forma,ActiveRecord::Base.logger = Logger.new(STDOUT)
alterará todo o log para todos os modelos.