Skip to content

Commit e01d1e2

Browse files
committed
ActiveSupport::LogSubscriber restore compatibility with SemanticLogger
Fix: rails#49563 The semantic_logger gems doesn't behave exactly like stdlib logger in that `SemanticLogger#level` returns a Symbol while stdlib `Logger#level` returns an Integer. Because of this we can't simply compare integers, we have to use the various `#{level}?` methods.
1 parent 2239749 commit e01d1e2

File tree

3 files changed

+96
-32
lines changed

3 files changed

+96
-32
lines changed

activesupport/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
* Fix compatibility with the `semantic_logger` gem.
2+
3+
The `semantic_logger` gem doesn't behave exactly like stdlib logger in that
4+
`SemanticLogger#level` returns a Symbol while stdlib `Logger#level` returns an Integer.
5+
6+
This caused the various `LogSubscriber` classes in Rails to break when assigned a
7+
`SemanticLogger` instance.
8+
9+
*Jean Boussier*, *ojab*
10+
111
* Fix MemoryStore to prevent race conditions when incrementing or decrementing.
212

313
*Pierre Jambet*

activesupport/lib/active_support/log_subscriber.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ class LogSubscriber < Subscriber
8686
mattr_accessor :colorize_logging, default: true
8787
class_attribute :log_levels, instance_accessor: false, default: {} # :nodoc:
8888

89+
LEVEL_CHECKS = {
90+
debug: -> (logger) { !logger.debug? },
91+
info: -> (logger) { !logger.info? },
92+
error: -> (logger) { !logger.error? },
93+
}
94+
8995
class << self
9096
def logger
9197
@logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
@@ -122,7 +128,7 @@ def set_event_levels
122128
end
123129

124130
def subscribe_log_level(method, level)
125-
self.log_levels = log_levels.merge(method => ::Logger.const_get(level.upcase))
131+
self.log_levels = log_levels.merge(method => LEVEL_CHECKS.fetch(level))
126132
set_event_levels
127133
end
128134
end
@@ -137,7 +143,7 @@ def logger
137143
end
138144

139145
def silenced?(event)
140-
logger.nil? || logger.level > @event_levels.fetch(event, Float::INFINITY)
146+
logger.nil? || @event_levels[event]&.call(logger)
141147
end
142148

143149
def call(event)

activesupport/test/log_subscriber_test.rb

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,44 @@
33
require_relative "abstract_unit"
44
require "active_support/log_subscriber/test_helper"
55

6-
class MyLogSubscriber < ActiveSupport::LogSubscriber
7-
attr_reader :event
6+
class SyncLogSubscriberTest < ActiveSupport::TestCase
7+
include ActiveSupport::LogSubscriber::TestHelper
88

9-
def some_event(event)
10-
@event = event
11-
info event.name
12-
end
9+
class MyLogSubscriber < ActiveSupport::LogSubscriber
10+
attr_reader :event
1311

14-
def foo(event)
15-
debug "debug"
16-
info { "info" }
17-
warn "warn"
18-
end
12+
def some_event(event)
13+
@event = event
14+
info event.name
15+
end
1916

20-
def bar(event)
21-
info "#{color("cool", :red)}, #{color("isn't it?", :blue, bold: true)}"
22-
end
17+
def foo(event)
18+
debug "debug"
19+
info { "info" }
20+
warn "warn"
21+
end
2322

24-
def baz(event)
25-
info "#{color("rad", :green, bold: true, underline: true)}, #{color("isn't it?", :yellow, italic: true)}"
26-
end
23+
def bar(event)
24+
info "#{color("cool", :red)}, #{color("isn't it?", :blue, bold: true)}"
25+
end
2726

28-
def deprecated(event)
29-
info "#{color("bogus", :red, true)}"
30-
end
27+
def baz(event)
28+
info "#{color("rad", :green, bold: true, underline: true)}, #{color("isn't it?", :yellow, italic: true)}"
29+
end
3130

32-
def puke(event)
33-
raise "puke"
34-
end
35-
end
31+
def deprecated(event)
32+
info "#{color("bogus", :red, true)}"
33+
end
3634

37-
class SyncLogSubscriberTest < ActiveSupport::TestCase
38-
include ActiveSupport::LogSubscriber::TestHelper
35+
def puke(event)
36+
raise "puke"
37+
end
38+
39+
def debug_only(event)
40+
debug "debug logs are enabled"
41+
end
42+
subscribe_log_level :debug_only, :debug
43+
end
3944

4045
def setup
4146
super
@@ -47,10 +52,6 @@ def teardown
4752
ActiveSupport::LogSubscriber.log_subscribers.clear
4853
end
4954

50-
def instrument(*args, &block)
51-
ActiveSupport::Notifications.instrument(*args, &block)
52-
end
53-
5455
def test_proxies_method_to_rails_logger
5556
@log_subscriber.foo(nil)
5657
assert_equal %w(debug), @logger.logged(:debug)
@@ -165,4 +166,51 @@ def test_logging_does_not_die_on_failures
165166
assert_equal 1, @logger.logged(:error).size
166167
assert_match 'Could not log "puke.my_log_subscriber" event. RuntimeError: puke', @logger.logged(:error).last
167168
end
169+
170+
def test_subscribe_log_level
171+
MyLogSubscriber.logger = @logger
172+
@logger.level = Logger::INFO
173+
MyLogSubscriber.attach_to :my_log_subscriber, @log_subscriber
174+
assert_empty @logger.logged(:debug)
175+
176+
instrument "debug_only.my_log_subscriber"
177+
wait
178+
assert_empty @logger.logged(:debug)
179+
180+
@logger.level = Logger::DEBUG
181+
instrument "debug_only.my_log_subscriber"
182+
wait
183+
assert_not_empty @logger.logged(:debug)
184+
end
185+
186+
class MockSemanticLogger < MockLogger
187+
LEVELS = [:debug, :info]
188+
def level
189+
LEVELS[super]
190+
end
191+
end
192+
193+
def test_subscribe_log_level_with_non_numeric_levels
194+
# The semantic_logger gem doesn't returns integers but symbols as levels
195+
@logger = MockSemanticLogger.new
196+
set_logger(@logger)
197+
MyLogSubscriber.logger = @logger
198+
@logger.level = Logger::INFO
199+
MyLogSubscriber.attach_to :my_log_subscriber, @log_subscriber
200+
assert_empty @logger.logged(:debug)
201+
202+
instrument "debug_only.my_log_subscriber"
203+
wait
204+
assert_empty @logger.logged(:debug)
205+
206+
@logger.level = Logger::DEBUG
207+
instrument "debug_only.my_log_subscriber"
208+
wait
209+
assert_not_empty @logger.logged(:debug)
210+
end
211+
212+
private
213+
def instrument(*args, &block)
214+
ActiveSupport::Notifications.instrument(*args, &block)
215+
end
168216
end

0 commit comments

Comments
 (0)