Respuestas:
Puede crear un objeto Logger usted mismo desde cualquier modelo. Simplemente pase el nombre del archivo al constructor y use el objeto como los Rails habituales 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
Aquí utilicé un atributo de clase para memorizar el registrador. De esta manera, no se creará para cada objeto de usuario que se cree, pero no es necesario que lo haga. Recuerde también que puede inyectar el my_logger
método directamente en la ActiveRecord::Base
clase (o en alguna superclase propia si no le gusta demasiado el parche de mono) para compartir el código entre los modelos de su aplicación.
User.logger = Logger.new(STDOUT)
cambió todo el registro para todos los modelos. Bueno, cambióActiveRecord::Base.logger
my_logger
en application_controller.rb
.
Actualizar
Hice una gema basada en la solución a continuación, llamada multi_logger . Solo haz esto en el inicializador:
MultiLogger.add_logger('post')
y llama
Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.
y listo
Si desea codificarlo usted mismo, consulte a continuación:
Una solución más completa sería colocar lo siguiente en su lib/
o config/initializers/
directorio.
El beneficio es que puede configurar el formateador para prefijar las marcas de tiempo o la gravedad de los registros automáticamente. Esto es accesible desde cualquier lugar en Rails, y se ve más ordenado usando el patrón 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
#{$$}
?
Una opción decente que funciona para mí es agregar una clase bastante simple a su app/models
carpeta, 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
luego en su controlador, o realmente en casi cualquier lugar donde pueda hacer referencia a la clase de un modelo desde su aplicación rails, es decir, en cualquier lugar que pueda hacer Post.create(:title => "Hello world", :contents => "Lorum ipsum");
o algo similar, puede iniciar sesión en su archivo personalizado de esta manera
MyLog.debug "Hello world"
Defina una clase de registrador en (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
Inicialice el registrador en (digamos) config / initializers / special_log.rb:
SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal
En cualquier lugar de su aplicación, puede iniciar sesión 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
Sugeriría usar la gema Log4r para el registro personalizado. Descripción de la cita de su página:
Log4r es una biblioteca de registro completa y flexible escrita en Ruby para usar en programas Ruby. Cuenta con un sistema de registro jerárquico de cualquier número de niveles, nombres de nivel personalizados, herencia del registrador, múltiples destinos de salida por evento de registro, seguimiento de ejecución, formato personalizado, seguridad de subprocesos, configuración XML y YAML, y más.
¡El marco de registro, con su nombre engañosamente simple, tiene la sofisticación que anhelas!
Siga las instrucciones breves de los rieles de inicio de sesión para comenzar a filtrar el ruido, recibir alertas y elegir la salida de una manera fina y de alto nivel.
Date una palmadita en la espalda cuando hayas terminado. Rollo de registro, todos los días. Vale la pena por eso solo.
User.logger = Logger.new(STDOUT)
o donde quiera iniciar sesión. Del mismo modo,ActiveRecord::Base.logger = Logger.new(STDOUT)
cambiará todo el registro de todos los modelos.