We want to have a collection of controllers where we route logger output from all actions and downstream methods to a separate log file. This is a Rails 3 project. In Rails 2 we
The reason that not all the stuff is redirected by controller filter, is that these “Started...” etc are written by rack middleware, that is executed before the controller was even instantiated.
So, to grab and redirect everything related to some condition, one should interfere deeper. Below is a [possibly incomplete] example on how to hack into the pipeline.
Define the middleware to switch loggers
module MyApp
class MyMiddleware
def initialize(app)
@app, @logger = app, Rails.logger
.instance_variable_get(:@logger)
.instance_variable_get(:@log)
@my_logger = Logger.new('reports_controller.log', ...)
end
def call(env)
# env['action_dispatch.logger'].inspect
#⇒ @log_dest=...>
# here we do not have a controller name
Rails.logger
.instance_variable_get(:@logger)
.instance_variable_set(:@log,
case env['PATH_INFO'] # or PATH_INFO, or whatever
when %r|\A/api/v1/| then @my_logger
else @logger
end
)
@app.call(env)
end
end
end
Add an initializer somewhere in config/initializers/my_logger.rb
Rails.application.middleware.insert_before \
Rails::Rack::Logger, MyApp::MyMiddleware
Please note, that Rails’ logger is a nested beast:
Rails::logger
#⇒ #
One might want to set a specific formatter on the logger, or even filter messages using regular expression there (though it should not be considered a good practice.)