2008-12-03 6 views

Respuesta

144

Puede crear un objeto Logger usted mismo desde cualquier modelo. Sólo tiene que pasar el nombre de archivo para el constructor y utilizar el objeto como los carriles 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í he utilizado un atributo de clase a memoize 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.

+3

Si desea cambiar todo el registro predeterminado para ese modelo específico, puede simplemente usar 'User.logger = Logger.new (STDOUT)' o donde quieras para iniciar sesión en. De la misma manera, 'ActiveRecord :: Base.logger = Logger.new (STDOUT)' cambiará todo el registro para todos los modelos. – Dave

+0

¿Alguien sabe cómo crear carpetas para cada registro? –

+1

@Dave He intentado su sugerencia y falló. 'User.logger = Logger.new (STDOUT)' cambió todos los registros para todos los modelos. Bueno, cambió 'ActiveRecord :: Base.logger' – fetsh

2
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 
31

Una opción decente que funciona para mí es simplemente agregar una clase bastante sencillo a la carpeta app/models 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 

entonces en su controlador, o en realidad en casi cualquier lugar que usted podría hacer referencia a una la clase de modelo de carriles dentro de su aplicación, es decir, en cualquier lugar que podía hacer Post.create(:title => "Hello world", :contents => "Lorum ipsum"); o algo similar puede conectarse a su archivo personalizado como este

MyLog.debug "Hello world" 
+0

¡Eres el hombre! – Bijan

+2

¡Solución inteligente y simple! – Anwar

35

Actualización

He hecho una joya basada en la solución a continuación, llamada multi_logger. Sólo hacer esto en el inicializador:

MultiLogger.add_logger('post') 

y llame

Rails.logger.post.error('hi') 
# or call logger.post.error('hi') if it is accessible. 

y ya está.

Si desea codificar por sí mismo, ver a continuación:


Una solución más completa sería colocar lo siguiente en su directorio o lib/config/initializers/.

La ventaja 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 
1

Yo sugeriría usar Log4r gem para el registro personalizado. Citando descripción de su página:

Log4r es una biblioteca completa y flexible de registro escrita en Ruby para su uso en programas de Ruby. Cuenta con un sistema de registro jerárquico de cualquier número de niveles , nombres de nivel personalizados, herencia de registrador, múltiples destinos de salida por evento de registro, seguimiento de ejecución, formateo personalizado, seguridad de hilos, XML y configuración YAML, y más.

0

¡La estructura de registro, con su nombre engañosamente simple, tiene la sofisticación que anhela!

Siga las instrucciones muy breves de logging-rails para empezar 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.

3

Aquí es mi costumbre registrador:

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 
1
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') 
2

definir una clase de logger (digamos) app/modelos/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 

inicializar el registrador de (digamos) config/initializers/special_log.rb:

SpecialLog.logger = Logger.new(SpecialLog::LogFile) 
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal 

Anyw aquí en su aplicación, puede iniciar sesión con:

SpecialLog.debug("something went wrong") 
# or 
SpecialLog.info("life is good") 
+0

¡Gracias, funciona como un encanto! –

Cuestiones relacionadas