Skip to content

Commit 308594b

Browse files
committed
Convert log subscriber in Active Record to consume structured events
1 parent 46b8605 commit 308594b

File tree

8 files changed

+128
-128
lines changed

8 files changed

+128
-128
lines changed

activerecord/lib/active_record/base.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "active_support/time"
77
require "active_support/core_ext/class/subclasses"
88
require "active_record/log_subscriber"
9+
require "active_record/structured_event_subscriber"
910
require "active_record/relation/delegation"
1011
require "active_record/attributes"
1112
require "active_record/type_caster"

activerecord/lib/active_record/log_subscriber.rb

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,42 @@
11
# frozen_string_literal: true
22

33
module ActiveRecord
4-
class LogSubscriber < ActiveSupport::LogSubscriber # :nodoc:
4+
class LogSubscriber < ActiveSupport::EventReporter::LogSubscriber # :nodoc:
55
IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"]
66

7+
self.namespace = "active_record"
8+
79
class_attribute :backtrace_cleaner, default: ActiveSupport::BacktraceCleaner.new
810

911
def strict_loading_violation(event)
1012
debug do
11-
owner = event.payload[:owner]
12-
reflection = event.payload[:reflection]
13-
color(reflection.strict_loading_violation_message(owner), RED)
13+
owner = event[:payload][:owner]
14+
klass = event[:payload][:class]
15+
name = event[:payload][:name]
16+
message = +"`#{owner}` is marked for strict_loading."
17+
message << " The #{klass ? "#{klass} association" : "polymorphic association"}"
18+
message << " named `:#{name}` cannot be lazily loaded."
19+
20+
color(message, RED)
1421
end
1522
end
16-
subscribe_log_level :strict_loading_violation, :debug
23+
event_log_level :strict_loading_violation, :debug
1724

1825
def sql(event)
19-
payload = event.payload
26+
payload = event[:payload]
2027

2128
return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
2229

2330
name = if payload[:async]
24-
"ASYNC #{payload[:name]} (#{payload[:lock_wait].round(1)}ms) (db time #{event.duration.round(1)}ms)"
31+
"ASYNC #{payload[:name]} (#{payload[:lock_wait].round(1)}ms) (db time #{payload[:duration_ms].round(1)}ms)"
2532
else
26-
"#{payload[:name]} (#{event.duration.round(1)}ms)"
33+
"#{payload[:name]} (#{payload[:duration_ms].round(1)}ms)"
2734
end
2835
name = "CACHE #{name}" if payload[:cached]
2936
sql = payload[:sql]
30-
binds = nil
37+
binds = payload[:binds]
3138

3239
if payload[:binds]&.any?
33-
casted_params = type_casted_binds(payload[:type_casted_binds])
34-
35-
binds = []
36-
payload[:binds].each_with_index do |attr, i|
37-
attribute_name = if attr.respond_to?(:name)
38-
attr.name
39-
elsif attr.respond_to?(:[]) && attr[i].respond_to?(:name)
40-
attr[i].name
41-
else
42-
nil
43-
end
44-
45-
filtered_params = filter(attribute_name, casted_params[i])
46-
47-
binds << render_bind(attr, filtered_params)
48-
end
4940
binds = binds.inspect
5041
binds.prepend(" ")
5142
end
@@ -55,7 +46,11 @@ def sql(event)
5546

5647
debug " #{name} #{sql}#{binds}"
5748
end
58-
subscribe_log_level :sql, :debug
49+
event_log_level :sql, :debug
50+
51+
def self.default_logger
52+
ActiveRecord::Base.logger
53+
end
5954

6055
private
6156
def type_casted_binds(casted_binds)
@@ -106,10 +101,6 @@ def sql_color(sql)
106101
end
107102
end
108103

109-
def logger
110-
ActiveRecord::Base.logger
111-
end
112-
113104
def debug(progname = nil, &block)
114105
return unless super
115106

@@ -136,4 +127,6 @@ def filter(name, value)
136127
end
137128
end
138129

139-
ActiveRecord::LogSubscriber.attach_to :active_record
130+
ActiveSupport.event_reporter.subscribe(
131+
ActiveRecord::LogSubscriber.new, &ActiveRecord::LogSubscriber.subscription_filter
132+
)

activerecord/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class DefaultEngineOptionTest < ActiveRecord::AbstractMysqlTestCase
8181
include SchemaDumpingHelper
8282
self.use_transactional_tests = false
8383

84+
def run(*)
85+
with_debug_event_reporting do
86+
super
87+
end
88+
end
89+
8490
def setup
8591
@logger_was = ActiveRecord::Base.logger
8692
@log = StringIO.new
@@ -90,7 +96,7 @@ def setup
9096
end
9197

9298
def teardown
93-
ActiveRecord::Base.logger = @logger_was
99+
ActiveRecord::Base.logger = @logger_was
94100
ActiveRecord::Migration.verbose = @verbose_was
95101
ActiveRecord::Base.lease_connection.drop_table "mysql_table_options", if_exists: true
96102
ActiveRecord::Base.connection_pool.schema_migration.delete_all_versions rescue nil

activerecord/test/cases/bind_parameter_test.rb

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require "models/reply"
66
require "models/author"
77
require "models/post"
8+
require "active_support/log_subscriber/test_helper"
89

910
if ActiveRecord::Base.lease_connection.prepared_statements
1011
module ActiveRecord
@@ -23,6 +24,12 @@ def call(*args)
2324
end
2425
end
2526

27+
def run(*)
28+
with_debug_event_reporting do
29+
super
30+
end
31+
end
32+
2633
def setup
2734
super
2835
@connection = ActiveRecord::Base.lease_connection
@@ -289,21 +296,12 @@ def assert_logs_binds(binds)
289296
123,
290297
payload)
291298

292-
logger = Class.new(ActiveRecord::LogSubscriber) {
293-
attr_reader :debugs
294-
295-
def initialize
296-
super
297-
@debugs = []
298-
end
299-
300-
def debug(str)
301-
@debugs << str
302-
end
303-
}.new
304-
305-
logger.sql(event)
306-
assert_match %r(\[\["id", 10\]\]\z), logger.debugs.first
299+
old_logger = ActiveRecord::LogSubscriber.logger
300+
ActiveRecord::LogSubscriber.logger = logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
301+
StructuredEventSubscriber.new.sql(event)
302+
assert_match %r(\[\["id", 10\]\]\z), logger.logged(:debug).last
303+
ensure
304+
ActiveRecord::LogSubscriber.logger = old_logger
307305
end
308306

309307
def assert_logs_unnamed_binds(binds)
@@ -321,21 +319,12 @@ def assert_logs_unnamed_binds(binds)
321319
123,
322320
payload)
323321

324-
logger = Class.new(ActiveRecord::LogSubscriber) {
325-
attr_reader :debugs
326-
327-
def initialize
328-
super
329-
@debugs = []
330-
end
331-
332-
def debug(str)
333-
@debugs << str
334-
end
335-
}.new
336-
337-
logger.sql(event)
338-
assert_match %r(\[\[nil, "abcd"\]\]\z), logger.debugs.first
322+
old_logger = ActiveRecord::LogSubscriber.logger
323+
ActiveRecord::LogSubscriber.logger = logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
324+
StructuredEventSubscriber.new.sql(event)
325+
assert_match %r(\[\[nil, "abcd"\]\]\z), logger.logged(:debug).last
326+
ensure
327+
ActiveRecord::LogSubscriber.logger = old_logger
339328
end
340329

341330
def assert_filtered_log_binds(binds)
@@ -353,21 +342,12 @@ def assert_filtered_log_binds(binds)
353342
123,
354343
payload)
355344

356-
logger = Class.new(ActiveRecord::LogSubscriber) {
357-
attr_reader :debugs
358-
359-
def initialize
360-
super
361-
@debugs = []
362-
end
363-
364-
def debug(str)
365-
@debugs << str
366-
end
367-
}.new
368-
369-
logger.sql(event)
370-
assert_match %r/#{Regexp.escape '[["auth_token", "[FILTERED]"]]'}/, logger.debugs.first
345+
old_logger = ActiveRecord::LogSubscriber.logger
346+
ActiveRecord::LogSubscriber.logger = logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
347+
StructuredEventSubscriber.new.sql(event)
348+
assert_match %r/#{Regexp.escape '[["auth_token", "[FILTERED]"]]'}/, logger.logged(:debug).last
349+
ensure
350+
ActiveRecord::LogSubscriber.logger = old_logger
371351
end
372352
end
373353
end

activerecord/test/cases/insert_all_test.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class ReadonlyNameBook < Book
1818
class InsertAllTest < ActiveRecord::TestCase
1919
fixtures :books
2020

21+
def run(*)
22+
with_debug_event_reporting do
23+
super
24+
end
25+
end
26+
2127
def setup
2228
Arel::Table.engine = nil # should not rely on the global Arel::Table.engine
2329
@original_db_warnings_action = :ignore
@@ -1034,12 +1040,12 @@ def test_upsert_without_unpersisted_records_has_no_deprecation
10341040
private
10351041
def capture_log_output
10361042
output = StringIO.new
1037-
old_logger, ActiveRecord::Base.logger = ActiveRecord::Base.logger, ActiveSupport::Logger.new(output)
1043+
old_logger, ActiveRecord::LogSubscriber.logger = ActiveRecord::LogSubscriber.logger, ActiveSupport::Logger.new(output)
10381044

10391045
begin
10401046
yield output
10411047
ensure
1042-
ActiveRecord::Base.logger = old_logger
1048+
ActiveRecord::LogSubscriber.logger = old_logger
10431049
end
10441050
end
10451051

0 commit comments

Comments
 (0)