ruby on rails - print - ¿Cómo registrar algo en Rails en un archivo de registro independiente?
ruby print in console (9)
¡El marco de registro, con su nombre engañosamente simple, tiene la sofisticación que anhelas!
Siga las instrucciones muy breves de logging-rails de logging-rails para comenzar a filtrar el ruido, recibir alertas y elegir la salida de una manera detallada y de alto nivel.
Date una palmadita en la espalda cuando hayas terminado. Log-rolling, todos los días. Vale la pena solo por eso.
En los rieles, deseo registrar cierta información en un archivo de registro diferente y no en el desarrollo.log o producción.log estándar. Quiero hacer este registro de una clase modelo.
Aquí está mi registrador personalizado:
class DebugLog
def self.debug(message=nil)
return unless Rails.env.development? and message.present?
@logger ||= Logger.new(File.join(Rails.root, ''log'', ''debug.log''))
@logger.debug(message)
end
end
Defina una clase de registrador en (por ejemplo) 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")
Sugiero usar Log4r gem para el registro personalizado. Citando la descripción de su página:
Log4r es una biblioteca de registro completa y flexible escrita en Ruby para su uso en programas de Ruby. Cuenta con un sistema de registro jerárquico de cualquier cantidad de niveles, nombres de nivel personalizados, herencia de registradores, múltiples destinos de salida por evento de registro, seguimiento de ejecución, formato personalizado, seguridad de hilos, configuración de XML y YAML, y más.
Una opción decente que funciona para mí es simplemente agregar una clase bastante simple a su carpeta de app/models/my_log.rb
como app/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 en casi cualquier lugar donde pueda hacer referencia a la clase de un modelo desde su aplicación de rieles, es decir, desde cualquier lugar donde pueda Post.create(:title => "Hello world", :contents => "Lorum ipsum");
o algo similar, puede iniciar sesión en su archivo personalizado como este
MyLog.debug "Hello world"
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 has terminado.
Si quiere codificarlo usted mismo, vea a continuación:
Una solución más completa sería colocar lo siguiente en su directorio lib/
o config/initializers/
.
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
Puede crear un objeto Logger desde dentro de cualquier modelo. Simplemente pase el nombre del archivo al constructor y use el objeto como el logger
Rails habitual:
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 forma, no se creará para cada objeto Usuario que se crea, pero no es necesario que lo haga. Recuerde también que puede inyectar el método my_logger
directamente en la clase ActiveRecord::Base
(o en alguna superclase suya si no le gusta demasiado el parche mono) para compartir el código entre los modelos de su aplicación.
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
class Post < ActiveRecord::Base
def initialize(attributes)
super(attributes)
@logger = Logger.new("#{Rails.root}/log/post.log")
end
def logger
@logger
end
def some_method
logger.info(''Test 1'')
end
end
ps = Post.new
ps.some_method
ps.logger.info(''Test 2'')
Post.new.logger.info(''Test 3'')