Add ActionController::Base.log_at
Allow setting a different log level per request.
This commit is contained in:
parent
29be48f5a5
commit
75a53297c7
|
@ -1,3 +1,14 @@
|
||||||
|
* `ActionController::Base.log_at` allows setting a different log level per request.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Use the debug level if a particular cookie is set.
|
||||||
|
class ApplicationController < ActionController::Base
|
||||||
|
log_at :debug, if: -> { cookies[:debug] }
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
*George Claghorn*
|
||||||
|
|
||||||
* Allow system test screen shots to be taken more than once in
|
* Allow system test screen shots to be taken more than once in
|
||||||
a test by prefixing the file name with an incrementing counter.
|
a test by prefixing the file name with an incrementing counter.
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ module ActionController
|
||||||
autoload :BasicImplicitRender
|
autoload :BasicImplicitRender
|
||||||
autoload :ImplicitRender
|
autoload :ImplicitRender
|
||||||
autoload :Instrumentation
|
autoload :Instrumentation
|
||||||
|
autoload :Logging
|
||||||
autoload :MimeResponds
|
autoload :MimeResponds
|
||||||
autoload :ParamsWrapper
|
autoload :ParamsWrapper
|
||||||
autoload :Redirecting
|
autoload :Redirecting
|
||||||
|
|
|
@ -123,6 +123,7 @@ module ActionController
|
||||||
ForceSSL,
|
ForceSSL,
|
||||||
DataStreaming,
|
DataStreaming,
|
||||||
DefaultHeaders,
|
DefaultHeaders,
|
||||||
|
Logging,
|
||||||
|
|
||||||
# Before callbacks should also be executed as early as possible, so
|
# Before callbacks should also be executed as early as possible, so
|
||||||
# also include them at the bottom.
|
# also include them at the bottom.
|
||||||
|
|
|
@ -234,6 +234,7 @@ module ActionController
|
||||||
HttpAuthentication::Digest::ControllerMethods,
|
HttpAuthentication::Digest::ControllerMethods,
|
||||||
HttpAuthentication::Token::ControllerMethods,
|
HttpAuthentication::Token::ControllerMethods,
|
||||||
DefaultHeaders,
|
DefaultHeaders,
|
||||||
|
Logging,
|
||||||
|
|
||||||
# Before callbacks should also be executed as early as possible, so
|
# Before callbacks should also be executed as early as possible, so
|
||||||
# also include them at the bottom.
|
# also include them at the bottom.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ActionController
|
||||||
|
module Logging
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
# Set a different log level per request.
|
||||||
|
#
|
||||||
|
# # Use the debug log level if a particular cookie is set.
|
||||||
|
# class ApplicationController < ActionController::Base
|
||||||
|
# log_at :debug, if: -> { cookies[:debug] }
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
def log_at(level, **options)
|
||||||
|
around_action ->(_, action) { logger.log_at(level, &action) }, **options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "abstract_unit"
|
||||||
|
|
||||||
|
class LoggingTest < ActionController::TestCase
|
||||||
|
class TestController < ActionController::Base
|
||||||
|
log_at :debug, if: -> { params[:level] == "debug" }
|
||||||
|
log_at :warn, if: -> { params[:level] == "warn" }
|
||||||
|
|
||||||
|
def show
|
||||||
|
render plain: logger.level
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tests TestController
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@logger = @controller.logger = ActiveSupport::Logger.new(nil, level: Logger::INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging at the default level" do
|
||||||
|
get :show
|
||||||
|
assert_equal Logger::INFO.to_s, response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging at a noisier level per request" do
|
||||||
|
assert_no_changes -> { @logger.level } do
|
||||||
|
get :show, params: { level: "debug" }
|
||||||
|
assert_equal Logger::DEBUG.to_s, response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging at a quieter level per request" do
|
||||||
|
assert_no_changes -> { @logger.level } do
|
||||||
|
get :show, params: { level: "warn" }
|
||||||
|
assert_equal Logger::WARN.to_s, response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -27,19 +27,8 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
# Silences the logger for the duration of the block.
|
# Silences the logger for the duration of the block.
|
||||||
def silence(temporary_level = Logger::ERROR)
|
def silence(severity = Logger::ERROR)
|
||||||
if silencer
|
silencer ? log_at(severity) { yield self } : yield(self)
|
||||||
begin
|
|
||||||
old_local_level = local_level
|
|
||||||
self.local_level = temporary_level
|
|
||||||
|
|
||||||
yield self
|
|
||||||
ensure
|
|
||||||
self.local_level = old_local_level
|
|
||||||
end
|
|
||||||
else
|
|
||||||
yield self
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,10 +37,15 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_level=(level)
|
def local_level=(level)
|
||||||
if level
|
case level
|
||||||
|
when Integer
|
||||||
self.class.local_levels[local_log_id] = level
|
self.class.local_levels[local_log_id] = level
|
||||||
else
|
when Symbol
|
||||||
|
self.class.local_levels[local_log_id] = Logger::Severity.const_get(level.to_s.upcase)
|
||||||
|
when nil
|
||||||
self.class.local_levels.delete(local_log_id)
|
self.class.local_levels.delete(local_log_id)
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Invalid log level: #{level.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,9 +53,17 @@ module ActiveSupport
|
||||||
local_level || super
|
local_level || super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Change the thread-local level for the duration of the given block.
|
||||||
|
def log_at(level)
|
||||||
|
old_local_level, self.local_level = local_level, level
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
self.local_level = old_local_level
|
||||||
|
end
|
||||||
|
|
||||||
# Redefined to check severity against #level, and thus the thread-local level, rather than +@level+.
|
# Redefined to check severity against #level, and thus the thread-local level, rather than +@level+.
|
||||||
# FIXME: Remove when the minimum Ruby version supports overriding Logger#level.
|
# FIXME: Remove when the minimum Ruby version supports overriding Logger#level.
|
||||||
def add(severity, message = nil, progname = nil, &block) # :nodoc:
|
def add(severity, message = nil, progname = nil, &block) #:nodoc:
|
||||||
severity ||= UNKNOWN
|
severity ||= UNKNOWN
|
||||||
progname ||= @progname
|
progname ||= @progname
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,41 @@ class LoggerTest < ActiveSupport::TestCase
|
||||||
assert_level(Logger::INFO)
|
assert_level(Logger::INFO)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_temporarily_logging_at_a_noisier_level
|
||||||
|
@logger.level = Logger::INFO
|
||||||
|
|
||||||
|
@logger.debug "NOT THERE"
|
||||||
|
|
||||||
|
@logger.log_at Logger::DEBUG do
|
||||||
|
@logger.debug "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
|
@logger.debug "NOT THERE"
|
||||||
|
|
||||||
|
assert_not_includes @output.string, "NOT THERE"
|
||||||
|
assert_includes @output.string, "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_temporarily_logging_at_a_quieter_level
|
||||||
|
@logger.log_at Logger::ERROR do
|
||||||
|
@logger.debug "NOT THERE"
|
||||||
|
@logger.error "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_not_includes @output.string, "NOT THERE"
|
||||||
|
assert_includes @output.string, "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_temporarily_logging_at_a_symbolic_level
|
||||||
|
@logger.log_at :error do
|
||||||
|
@logger.debug "NOT THERE"
|
||||||
|
@logger.error "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_not_includes @output.string, "NOT THERE"
|
||||||
|
assert_includes @output.string, "THIS IS HERE"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def level_name(level)
|
def level_name(level)
|
||||||
::Logger::Severity.constants.find do |severity|
|
::Logger::Severity.constants.find do |severity|
|
||||||
|
|
Loading…
Reference in New Issue