rubyonrails rails help guias basics ruby-on-rails ruby-on-rails-4 logging rack

ruby-on-rails - rails - ruby rack web server



Redirigir la salida del registrador para un controlador especĂ­fico en Rails 4 (3)

Después de hackear el código de Rails por un día, creo que he encontrado una solución de hack-ish para su problema.

Debe editar el método de call e initialize método de la siguiente manera:

def initialize(app) @app = app @logger = Rails.instance_variable_get(:@logger) @reports_api_controller_logger = Logger.new( Rails.root.join(''log'', REPORTS_API_CONTROLLER_LOGFILE), 10, 1000000) end def call(env) if env[''PATH_INFO''] =~ /api//v.*//reports.*/ Rails.instance_variable_set(:@logger, @reports_api_controller_logger) ActionController::Base.logger = @reports_api_controller_logger ActiveRecord::Base.logger = @reports_api_controller_logger ActionView::Base.logger = @reports_api_controller_logger else Rails.instance_variable_set(:@logger, @logger) ActionController::Base.logger = @logger ActiveRecord::Base.logger = @logger ActionView::Base.logger = @logger end @app.call(env) end

Esta es realmente una solución pirata y modifica la expresión regular de acuerdo con sus necesidades.

Dime si esto no funciona para ti.

He creado una solución basada en la respuesta en mi pregunta anterior. Redirigir la salida del registrador para un controlador específico en Rails 3 para Rails 3. Sin embargo, ahora funciona bien. Estoy tratando de aplicar la misma solución basada en middleware a un proyecto de Rails 4, pero hay Hay algunas diferencias que impiden que la misma solución funcione.

La solución Rails 3:

module MyApp class LoggerMiddleware REPORTS_API_CONTROLLER_PATH = %r|/A/api/v.*/reports.*| REPORTS_API_CONTROLLER_LOGFILE = "reports_controller.log" def initialize(app) @app = app @logger = Rails::logger .instance_variable_get(:@logger) .instance_variable_get(:@log) @reports_api_controller_logger = Logger.new( Rails.root.join(''log'', REPORTS_API_CONTROLLER_LOGFILE), 10, 1000000) end def call(env) Rails::logger .instance_variable_get(:@logger) .instance_variable_set(:@log, case env[''PATH_INFO''] when REPORTS_API_CONTROLLER_PATH then @reports_api_controller_logger else @logger end ) @app.call(env) end end end Rails.application.middleware.insert_before Rails::Rack::Logger, MyApp::LoggerMiddleware

en lo anterior:

Captador de Rails 3 para Rails.logger = Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log)

El instalador de Rails 3 para Rails.logger (configurando a @my_logger) = Rails::logger.instance_variable_get(:@logger).instance_variable_set(:@log,@my_logger)

Una cosa que he notado de inmediato es que en Rails 4 el Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log) devuelve nil.

Comprobando en la consola de Rails 4, veo que Rails.instance_variable_get(:@logger) devuelve #<ActiveSupport::Logger:0x007f84ff503a08 ....>

He intentado reemplazar el getter con Rails.instance_variable_get(:@logger) y el setter con Rails.instance_variable_set(:@logger,my_logger) y casi parece funcionar. La primera parte de la actividad, "Comenzado ..." va al nuevo archivo de registro, pero todo lo que va después va al archivo de registro predeterminado (el Rails.logger antes de que el middleware lo cambiara).

Cualquiera de Rails.instance_variable_get(:@logger) no es el nivel más bajo equivalente en Rails 4 a Rails 3 Rails::logger.instance_variable_get(:@logger).instance_variable_get(:@log) para obtener / configurar Rails.logger o allí es algo más adelante en el proceso después de mi middleware que está sobrescribiendo esto después de configurarlo.

¿Alguna pista?

Actualizar:

Para aclarar, la solución publicada anteriormente funciona como se espera en Rails 3. Cualquier limitación que pueda tener o no en entornos especiales (por ejemplo, si la solución puede no funcionar en entornos de servidor de subprocesos si ese es el caso) está bien en este punto y no se experimentan como obstáculos en este momento, por lo tanto, estas mismas limitaciones también están bien en una solución de Rails 4 para esta pregunta.


El enfoque de utilizar una clase de registro diferente para 1 controlador tiene el inconveniente de que no funcionará en un servidor de subprocesos que está de moda en estos días, no solo con JRuby, sino también con MRI gracias a Heroku

La única idea que tengo hasta ahora después de una semana de reflexión es canalizar los registros a syslog y usar las instalaciones de syslog para dividirlos en archivos separados.

Seguiría siendo necesario parchear el Logger para que incluya cadenas que permitan la división (como agregar una línea con formato desde la traza de #caller a los archivos de registro).

El plan B sería introducir mi propio registrador y simplemente registrar lo que necesito en ese controlador. Podría fácilmente volcar parámetros y respuestas, por ejemplo, si eso es suficiente


No estoy seguro de si necesita enfocar la solución de la misma manera que lo hizo en Rails 3. Parece que puede haber otras formas de lograr su objetivo final. ¿Has considerado alguno de estos enfoques o gemas?

https://github.com/TwP/logging

¿Cómo registrar algo en Rails en un archivo de registro independiente?

A veces, intentar algo completamente diferente de lo que ya ha hecho puede ser útil en mi humilde opinión

Esto es un poco de conjetura, pero esta puede ser la razón por la que sus preparadores de obtención no funcionan como se esperaba: https://github.com/rails/rails/commit/6329d9fa8b2f86a178151be264cccdb805bfaaac

Con respecto a la solución de Jagjot y la necesidad de establecer un registro base para cada una de las Clases de Acción de MVC, Rails 4 establece estos por separado de forma predeterminada, lo que en definitiva ofrecerá más flexibilidad de forma inmediata. http://guides.rubyonrails.org/configuring.html#initializers