aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG2
-rw-r--r--railties/guides/code/getting_started/config/environments/production.rb3
-rw-r--r--railties/lib/rails/application.rb2
-rw-r--r--railties/lib/rails/application/bootstrap.rb4
-rw-r--r--railties/lib/rails/application/configuration.rb2
-rw-r--r--railties/lib/rails/rack.rb1
-rw-r--r--railties/lib/rails/rack/logger.rb4
-rw-r--r--railties/lib/rails/rack/tagged_logging.rb39
8 files changed, 52 insertions, 5 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 187dd2428f..181019f851 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.2.0 (unreleased)*
+* Added Rails::Rack::TaggedLogging middleware by default that will apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications [DHH]
+
* Default options to `rails new` can be set in ~/.railsrc [Guillermo Iguaran]
* Added destroy alias to Rails engines. [Guillermo Iguaran]
diff --git a/railties/guides/code/getting_started/config/environments/production.rb b/railties/guides/code/getting_started/config/environments/production.rb
index 6ab63d30a6..4618191d6b 100644
--- a/railties/guides/code/getting_started/config/environments/production.rb
+++ b/railties/guides/code/getting_started/config/environments/production.rb
@@ -33,6 +33,9 @@ Blog::Application.configure do
# See everything in the log (default is :info)
# config.log_level = :debug
+ # Prepend all log lines with the following tags
+ # config.log_tags = [ :subdomain, :uuid ]
+
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index cbb2d23238..a097cfd1be 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -164,6 +164,8 @@ module Rails
middleware.use ::Rack::Lock unless config.allow_concurrency
middleware.use ::Rack::Runtime
middleware.use ::Rack::MethodOverride
+ middleware.use ::ActionDispatch::RequestId
+ middleware.use ::Rails::Rack::TaggedLogging, config.log_tags
middleware.use ::Rails::Rack::Logger # must come after Rack::MethodOverride to properly log overridden methods
middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 0aff05b681..c2cb121e42 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -24,12 +24,12 @@ module Rails
initializer :initialize_logger, :group => :all do
Rails.logger ||= config.logger || begin
path = config.paths["log"].first
- logger = ActiveSupport::BufferedLogger.new(path)
+ logger = ActiveSupport::TaggedLogging.new(ActiveSupport::BufferedLogger.new(path))
logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
logger.auto_flushing = false if Rails.env.production?
logger
rescue StandardError
- logger = ActiveSupport::BufferedLogger.new(STDERR)
+ logger = ActiveSupport::TaggedLogging.new(ActiveSupport::BufferedLogger.new(STDERR))
logger.level = ActiveSupport::BufferedLogger::WARN
logger.warn(
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 448521d2f0..8f5b28faf8 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -8,7 +8,7 @@ module Rails
attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets,
:cache_classes, :cache_store, :consider_all_requests_local,
:dependency_loading, :filter_parameters,
- :force_ssl, :helpers_paths, :logger, :preload_frameworks,
+ :force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks,
:reload_plugins, :secret_token, :serve_static_assets,
:ssl_options, :static_cache_control, :session_options,
:time_zone, :whiny_nils
diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb
index d1ee96f7fd..b78293e570 100644
--- a/railties/lib/rails/rack.rb
+++ b/railties/lib/rails/rack.rb
@@ -3,5 +3,6 @@ module Rails
autoload :Debugger, "rails/rack/debugger"
autoload :Logger, "rails/rack/logger"
autoload :LogTailer, "rails/rack/log_tailer"
+ autoload :TaggedLogging, "rails/rack/tagged_logging"
end
end
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
index 3be262de08..4d388c4d10 100644
--- a/railties/lib/rails/rack/logger.rb
+++ b/railties/lib/rails/rack/logger.rb
@@ -21,8 +21,8 @@ module Rails
request = ActionDispatch::Request.new(env)
path = request.filtered_path
- info "\n\nStarted #{request.request_method} \"#{path}\" " \
- "for #{request.ip} at #{Time.now.to_default_s}"
+ info "\n\n"
+ info "Started #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}"
end
def after_dispatch(env)
diff --git a/railties/lib/rails/rack/tagged_logging.rb b/railties/lib/rails/rack/tagged_logging.rb
new file mode 100644
index 0000000000..7980319b37
--- /dev/null
+++ b/railties/lib/rails/rack/tagged_logging.rb
@@ -0,0 +1,39 @@
+module Rails
+ module Rack
+ # Enables easy tagging of any logging activity that occurs within the Rails request cycle. The tags are configured via the
+ # config.log_tags setting. The tags can either be strings, procs taking a request argument, or the symbols :uuid or :subdomain.
+ # The latter two are then automatically expanded to request.uuid and request.subdaomins.first -- the two most common tags
+ # desired in production logs.
+ class TaggedLogging
+ def initialize(app, tags = nil)
+ @app, @tags = app, tags
+ end
+
+ def call(env)
+ if @tags
+ Rails.logger.tagged(compute_tags(env)) { @app.call(env) }
+ else
+ @app.call(env)
+ end
+ end
+
+ private
+ def compute_tags(env)
+ request = ActionDispatch::Request.new(env)
+
+ @tags.collect do |tag|
+ case tag
+ when Proc
+ tag.call(request)
+ when :uuid
+ request.uuid
+ when :subdomain
+ request.subdomains.first
+ else
+ tag
+ end
+ end
+ end
+ end
+ end
+end