可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is it possible to get the full URLs in the logs of a Rails application? Currently I'm getting something like:
Started GET "/" for 127.0.0.1 at 2011-08-27 13:13:10 +0200
but I need to get:
Started GET "http://localhost:3000/" for 127.0.0.1 at 2011-08-27 13:13:10 +0200
because this is an app where the domains are important.
回答1:
As of Rails 3.2.12, instead of monkey-patching before_dispatch or call_app, there is now a method that receives the request and returns the Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
bit.
So you can instead override that method in your own logger or monkey patch just that method.
# or "class Rails::Rack::Logger < ActiveSupport::LogSubscriber" for monkey patch class URLLogger < Rails::Rack::Logger def started_request_message(request) 'Started %s "%s%s%s" for %s at %s' % [ request.request_method, request.protocol, request.host_with_port, request.filtered_path, request.ip, Time.now.to_default_s ] end end
If you subclass don't forget to modify the middleware chain in config/application.rb
(and make sure URLLogger is loaded before the configuration block):
config.middleware.insert_before(Rails::Rack::Logger, URLLogger) config.middleware.delete(Rails::Rack::Logger)
回答2:
The line is coming from the middleware Rails::Rack::Logger
, which is in railties. At the simplest, you could just override the method doing the logging, e.g., in an initializer:
class Rails::Rack::Logger < ActiveSupport::LogSubscriber protected def before_dispatch(env) request = ActionDispatch::Request.new(env) info "\n\nStarted #{request.request_method} \"#{request.url}\" for #{request.ip} at #{Time.now.to_default_s}" end end
If you'd rather not override the logger, you could always add your own, which you've already created, then delete Rails::Rack::Logger
from the stack via:
config.middleware.insert_before(Rails::Rack::Logger, YourLogger) config.middleware.delete(Rails::Rack::Logger)
If you go this route you might check out the rack logger for its usage of ActionDispatch::Request
, and be sure to do the other job it does of flushing the log subscriber cache after dispatch, via ActiveSupport::LogSubscriber.flush_all!
回答3:
I don't think you can do this without changing Rails itself, which isn't nice, but you can add your own log call:
class ApplicationController < ActionController::Base before_filter :log_request protected def log_request logger.info("Started #{request.method} #{request.url}") end end
回答4:
A workaround I'm using for now was creating this class:
class HostnameLogger def initialize(app) @app = app end def call(env) uri = env["REQUEST_URI"] if uri.blank? # While testing a Rails app, there's no env["REQUEST_UIR"] defined. uri = "http://#{env["HTTP_HOST"]}#{env["PATH_INFO"]}" end Rails.logger.info "Started #{env["REQUEST_METHOD"]} \"#{uri}\" for #{env["REMOTE_ADDR"]} at #{Time.now}" @app.call(env) end end
and then adding it as Rack middleware (in application.rb):
config.middleware.use "HostnameLogger"
so I get:
Started GET "/users/login" for 127.0.0.1 at 2011-08-27 15:33:40 +0200
Started GET "http://localhost:3000/users/login" for 127.0.0.1 at 2011-08-27 15:33:40 +0200
回答5:
Rails::Rack::Logger.class_eval do protected def started_request_message(request) "Started #{request.request_method} \"#{request.url}\" for #{request.ip} at #{Time.now.to_default_s}" end end